根据VTune,使用OpenMP时“平均物理核心利用率”较低,不确定总体情况是什么

时间:2019-03-08 04:18:29

标签: multithreading performance optimization openmp vtune

我一直在优化光线跟踪器,并且为了获得更好的速度,我一般使用OpenMP,如下所示(C ++):

Accelerator accelerator;  // Has the data to make tracing way faster
Rays rays;                // Makes the rays so they're ready to go

#pragma omp parallel for
for (int y = 0; y < window->height; y++) {
    for (int x = 0; x < window->width; x++) {
        Ray& ray = rays.get(x, y);
        accelerator.trace(ray);
    }
}

我在6核/ 12线程CPU上获得了4.85倍的性能。我以为我会得到更多,也许是6到8倍...尤其是当它消耗了应用程序处理时间的99%以上时。

我想找出性能瓶颈在哪里,所以我打开了VTune并进行了概要分析。请注意,我是剖析的新手,所以也许这很正常,但这是我得到的图形:

enter image description here

特别是,这是第二大时间消耗者:

enter image description here

其中58%是微架构使用率。

尝试独自解决此问题,我一直在寻找有关此问题的信息,但我能找到的最多的是英特尔的VTune Wiki页面:

  

平均物理核心利用率

     

指标说明

     

该度量标准通过计算应用程序显示平均物理内核利用率。不计算旋转时间和开销时间。理想的平均CPU利用率等于物理CPU内核数。

我不确定这是想告诉我什么,这使我想到了我的问题:

这样的结果正常吗?还是某个地方出了问题?只能以4.8倍的速度(与理论上的最大值12.0相比)进行令人尴尬的并行处理吗?虽然光线跟踪本身可能会因光线反弹而变得不友好,但我已尽我所能来压缩内存并尽可能做到对缓存友好,使用利用SIMD进行计算的库,从文献中进行了无数次实现以加快处理速度,并尽可能避免分支并且不进行递归。我还并行化了光线,因此没有错误的共享AFAIK,因为每一行都是由一个线程完成的,因此不应为任何线程编写任何缓存行(特别是因为光线遍历都是const)。另外,帧缓冲区是行主要的,因此我希望假共享不会成为问题。

我不知道探查器是否会选择使用OpenMP进行线程化的主循环,这是预期的结果,或者我是否遇到某种新手错误并且没有获得所需的吞吐量。我还检查了它产生了12个线程,而OpenMP产生了。

我猜是tl; dr,我在使用OpenMP搞砸了吗?从我收集的数据来看,平均物理核心利用率应该接近平均逻辑核心利用率,但是我几乎可以肯定不知道我在说什么。

1 个答案:

答案 0 :(得分:1)

天哪,您做对了,您高估了并行执行的效率。您没有提供有关所使用的体系结构(CPU,内存等)的详细信息,也没有提供代码...但是要简单地说,我认为超出4.8倍的速度会达到内存带宽限制,因此RAM速度是你的瓶颈。

为什么?

正如您所说,光线跟踪并不难并行运行,而且您做得对,因此,如果CPU不是100%繁忙,我想您的内存控制器就是这样。 假设您正在跟踪RAM中的模型(三角形?体素?),则在检查命中时,射线需要读取模型的某些位。您应该检查最大RAM带宽,然后将其除以12(线程),然后除以每秒的射线数...然后发现,当跟踪大量射线时,即使40 GB / s也“不是那么多” 。因此,GPU是光线追踪的更好选择。

长话短说,我建议您尝试分析内存使用情况。