繁体   English   中英

为什么这个for循环使用OpenMP不会更快?

[英]Why is this for loop not faster using OpenMP?

我从一个更大的2D程序中提取了这个简单的成员函数,它所做的只是一个for循环访问三个不同的数组并进行数学运算(1D卷积)。 我一直在测试使用OpenMP来加快这个特定的功能:

void Image::convolve_lines()
{
  const int *ptr0 = tmp_bufs[0];
  const int *ptr1 = tmp_bufs[1];
  const int *ptr2 = tmp_bufs[2];
  const int width = Width;
#pragma omp parallel for
  for ( int x = 0; x < width; ++x )
    {
    const int sum = 0
      + 1 * ptr0[x]
      + 2 * ptr1[x]
      + 1 * ptr2[x];
    output[x] = sum;
    }
}

如果我在debian / wheezy amd64上使用gcc 4.7,整个程序在8 CPU机器上执行速度要慢很多。 如果我在debian / jessie amd64上使用gcc 4.9(在这台机器上只有4个CPU),整个程序执行的差别很小。

使用time进行比较:单核运行:

$ ./test black.pgm out.pgm  94.28s user 6.20s system 84% cpu 1:58.56 total

多核运行:

$ ./test black.pgm out.pgm  400.49s user 6.73s system 344% cpu 1:58.31 total

哪里:

$ head -3 black.pgm
P5
65536 65536
255

因此在执行期间Width设置为65536

如果那样,我使用cmake进行编译:

add_executable(test test.cxx)
set_target_properties(test PROPERTIES COMPILE_FLAGS "-fopenmp" LINK_FLAGS "-fopenmp")

并且CMAKE_BUILD_TYPE设置为:

CMAKE_BUILD_TYPE:STRING=Release

这意味着-O3 -DNDEBUG

我的问题是,为什么这个for循环使用多核不会更快? 阵列上没有重叠,openmp应该平均分割内存。 我不知道瓶颈来自哪里?

编辑:因为它被评论,我将我的输入文件更改为:

$ head -3 black2.pgm
P5
33554432 128
255

因此在执行期间Width现在设置为33554432 (应该考虑足够)。 现在时间显示:

单核运行:

$ ./test ./black2.pgm out.pgm  100.55s user 5.77s system 83% cpu 2:06.86 total

多核运行(由于某种原因,cpu%总是低于100%,这表明根本没有线程):

$ ./test ./black2.pgm out.pgm  117.94s user 7.94s system 98% cpu 2:07.63 total

我有一些一般性评论:

1.在优化代码之前,请确保数据是16字节对齐的。 这对于想要应用的优化非常重要。 如果数据被分成3个部分,最好添加一些虚拟元素,使3个部分的起始地址全部为16字节对齐。 通过这样做,CPU可以轻松地将数据加载到缓存行中。

2.在实现openMP之前,确保简单函数已向量化 大多数情况下,使用AVX / SSE指令集应该可以为您提供2到8倍的单线程改进。 对于您的情况非常简单:创建一个恒定的mm256寄存器并将其设置为值2,并将8个整数加载到3个mm256寄存器。 使用Haswell处理器,可以一起完成一次加法和一次乘法。 所以理论上,如果AVX管道可以填充,循环应该加速12倍!

3.有时并行化会降低性能 :现代CPU需要数百到数千个时钟周期才能预热,进入高性能状态并扩展频率。 如果任务不够大,很可能在CPU预热之前完成任务,并且无法通过并行获得速度提升。 并且不要忘记openMP也有开销:线程创建,同步和删除。 另一种情况是内存管理不善。 数据访问非常分散,所有CPU内核都处于空闲状态并等待来自RAM的数据。

我的建议:

您可能想尝试英特尔MKL,不要重新发明轮子。 该库经过极端优化,没有浪费时钟周期。 可以与串行库或并行版本链接,如果可以并行,则可以保证速度提升。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM