为什么OpenMP'simd'比'parallel for simd'具有更好的性能?

Ada*_*dam 0 c++ concurrency performance openmp

我正在使用英特尔编译器OpenMP 4.0开发Intel E5(6核,12个线程)

为什么这段代码SIMD-ed比并行SIMD-ed更快?

for (int suppv = 0; suppv < sSize; suppv++) {
  Value *gptr = &grid[gind];
  const Value * cptr = &C[cind];

  #pragma omp simd // vs. #pragma omp parallel for simd
  for (int suppu = 0; suppu < sSize; suppu++)
    gptr[suppu] += d * cptr[suppu];

  gind += gSize;
  cind += sSize;
}
Run Code Online (Sandbox Code Playgroud)

随着更多线程,它变得更慢.


编辑1:*grid是4096*4096矩阵,数据结构:vector<complex<double>> *C2112*129*129矩阵,数据结构:vector<complex<double>> *gSize = 4096*sSize = 129.

  • 编译器标志:icpc -march = native -std = c ++ 11 -qopt-report-phase = vec -qopt-report = 3 -O2 -openmp
  • 计时器:使用POSIX times()API的返回值diff.(它使用挂钟进行并发,我做了检查)

  • E5螺纹1 SIMD需要:291.520000(s)

  • E5线程2 for-SIMD需要:1039.220000(s)
  • E5螺纹12 for-SIMD需要:1684.270000(s)

a3m*_*ord 5

如果sSize= 129,就像编辑中那样,那么并行化循环的开销就不会有回报.如果你向我们展示顺序实现(没有SIMD)和纯并行实现(即有#pragma omp parallel for没有SIMD)的数量,这将更容易确认.

可能发生的事情是即使纯粹的并行版本也比顺序版本慢.当您为最外层循环的每次迭代启动/创建并行区域时,不仅会减小循环大小.

至于SIMD版本,这个问题基本上是为此量身定制的:你有一个高度可矢量化的内核,它太小而不能在线程之间分配.