关于 Direct2D 绘图调用中的多线程
Posted
技术标签:
【中文标题】关于 Direct2D 绘图调用中的多线程【英文标题】:About multithreading in a Direct2D drawing call 【发布时间】:2014-06-26 12:00:20 【问题描述】:序言
好吧...我知道这个问题可能涉及多个主题,但我对 DirectX 以及多线程以及我到目前为止阅读的 ***+MSDN 文章完全没有帮助。因此,我非常感谢 每条 将我推向正确方向的评论。
前提
几周前我开始编写一个Direct2D
渲染器,它绘制了我放入其中的一些矩阵并在单个窗口中绘制它(顺便说一句,效果很好)。
我试图加快计算速度并得到使用openMP
的提示。使用 pragma 语句时,我的程序使用 3 个线程而不是 1 个线程 - 我猜这很好。但我没有注意到任何加速。然而,这不是最重要的部分。绘图调用占用的时间比我计算矩阵的时间要多 很多。而且我不知道如何加快速度。
问题
请告诉我应该注意什么或如何加快/多线程我的绘图调用。
注意:我使用的是 STL、Windows 和 DirectX 标头,但没有 .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();
【问题讨论】:
一些我已经找到并阅读过的资源,但还没有帮助回答我的问题:SO: Best practices for multithreading in D2D、SO: Multithreading in D2D、BatchBatchBatch 以及链接的 MSDN 文章那些 *** 线程。 【参考方案1】:如果您使用的是 Win8 或更高版本,请确保在创建 Direct2D 设备上下文时设置了D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS 选项。
指定此标志后,Direct2D 将在 系统上存在的所有逻辑核心,它们可以 显着减少整体渲染时间。
目前,此标志仅适用于几何图形,并且需要 HAL。
从 Windows 8.1 开始,此标志仅影响路径几何渲染。它 对仅包含其他原始类型的场景没有影响(例如 文本、位图或几何实现)。
此标志在软件中渲染时也没有影响(即当 使用 WARP Direct3D 设备进行渲染)。控制软件 多线程,调用者应该使用 D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS 标志何时 创建 WARP Direct3D 设备。
指定此标志可以增加渲染期间的峰值工作集 并且还可以增加已经存在的应用程序中的线程争用 利用多线程处理。
您可能还想考虑geometry realizations。我发现当有大量几何对象要渲染时,这会产生明显的差异,但是您必须针对您的场景进行分析。椭圆是一种简单的几何体,因此您可能看不到明显的增益,尤其是当您必须转换到渲染位置时。
OpenMP(或任何其他 GPU api)在简单任务上可能会提供更差的性能,因为必须创建“视图”并将数据复制到视图和从视图复制数据的开销。确保您从使用 OpenMP 中受益于特定任务,并确保您的分析包含上述步骤。
请记住,线程的创建和调度会产生大量开销。通常,通过使代码尽可能简单,而不是处理调度和同步,您会看到更好的性能。然而,精心规划的线程可以带来巨大的收益,尤其是当它们不操纵相同的资源(或数据)时。
查看您的渲染过程,并尝试确定您的任何代码是否必须重新计算未更改的任何内容(大小、位置等)。在响应窗口大小更改时执行这些任务。注意你的结构对齐(内存边界)和数据的局部性(缓存未命中是昂贵的)。希望这会有所帮助。
【讨论】:
以上是关于关于 Direct2D 绘图调用中的多线程的主要内容,如果未能解决你的问题,请参考以下文章