c++ - 关于 Direct2D 绘图调用中的多线程

标签 c++ multithreading directx direct2d

序言

好吧...我知道这个问题可能涵盖多个主题,但我对 DirectX 和多线程完全陌生,而且我到目前为止阅读的 Stackoverflow+MSDN 文章对我没有任何帮助。因此,我非常感谢每一条评论,它们将我推向正确的方向。

前提

几周前,我开始编写一个 Direct2D 渲染器,它会绘制一些我放入其中的矩阵,并在单个窗口中绘制它(顺便说一句,效果很好)。

我试图加快计算速度,并得到了使用openMP的提示。当使用 pragma 语句时,我的 progrman 使用 3 个线程而不是 1 个 - 我想这很好。但我没有注意到任何加速。但这还不是最糟糕的部分。绘图调用比我计算矩阵花费的时间多很多。我不知道如何才能加快速度。

问题

请告诉我应该注意什么或者如何加快/多线程我的绘图调用。

注意:我使用 STL、Windows 和 DirectX header ,但没有 .NET、MFC/ATL 或类似库。

代码示例

vector<dot> set computeMatrix(ushort x, ushort y)
{
   // init set
   #pragma omp parallel for
   for(i=0; i<y; ++i)
     for(j=0; j<x; ++j)
        //do some computation
   return set;
}

dot 是一个 D2D1 椭圆对象。

void draw(vector<dot> set)
{
  pRenderTarget->BeginDraw();
  pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
  #pragma omp parallel for
  for(auto coord: set)
  {
    // set the pBrush
    pRenderTarget->FillEllipse(dot, pBrush);
  }
  pRenderTarget->EndDraw();
}

最佳答案

如果您使用的是Win8或以上版本,请确保您已设置D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS创建 Direct2D 设备上下文时的选项。

When this flag is specified, Direct2D will distribute rendering across all of the logical cores present on the system, which can significantly decrease overall rendering time.

目前,此标志仅适用于几何图形,并且需要 HAL。

As of Windows 8.1, this flag only affects path geometry rendering. It has no impact on scenes containing only other primitive types (such as text, bitmaps, or geometry realizations).

This flag also has no impact when rendering in software (i.e. when rendering with a WARP Direct3D device). To control software multithreading, callers should use the D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS flag when creating the WARP Direct3D device.

Specifying this flag can increase peak working set during rendering and can also increase thread contention in applications that already take advantage of multithreaded processing.

您可能还想考虑geometry realizations 。我发现当有大量几何对象需要渲染时,这会产生明显的差异,但是您必须针对您的场景进行分析。椭圆是一个简单的几何体,因此您可能看不到明显的增益,特别是当您必须平移到渲染位置时。

由于必须创建“ View ”并将数据复制到 View 或从 View 复制数据的开销,OpenMP(或任何其他 GPU api)在简单任务上的性能可能会差很多。确保您的特定任务能从使用 OpenMP 中受益,并确保您的分析包括上述步骤。

请记住,线程的创建和调度会产生大量开销。通常,通过使代码尽可能简单而不处理调度和同步,您会看到更好的性能。尽管如此,精心规划的线程可以带来巨大的 yield ,特别是当它们不操作相同的资源(或数据)时。

查看您的渲染 channel ,并尝试确定您的任何代码是否必须重新计算任何未更改的内容(大小、位置等)。响应窗口大小更改时执行这些任务。注意结构对齐(内存边界)和数据局部性(缓存未命中的代价很高)。希望这会有所帮助。

关于c++ - 关于 Direct2D 绘图调用中的多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24429971/

相关文章:

c++ - C++ 禁止指针和整数的比较

c++ - MinGW 和添加库

c++ - 如何在完整的专用模板类定义之外定义模板成员函数?

java - 访问静态字段的静态同步方法

directx - Direct3D11 : "gradient instruction used in a loop with varying iteration, forcing loop to unroll", 警告:X3570

c++ - WP8.1 认证 - 6.5.1 - 使用 XAML/C++ 的初始启动功能

c++ - 从字符串转换为整数的函数正在反向输出整数

java - 使用两个线程写入/读取 Vector(或 ArrayList)

android - 发布在另一个可运行的可运行未执行

c# - 如何在 C#/.NET/DirectX 中检索 mp3 音频文件的正确持续时间?