为什么OpenMP' simd'对于simd'有更好的性能而不是&

时间:2015-03-15 09:01:59

标签: c++ performance concurrency openmp

我正在使用英特尔编译器OpenMP 4.0处理英特尔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;
}

使用更多线程,它会变慢。


编辑1:   * grid是一个4096 * 4096矩阵,数据结构:vector<complex<double>>   * C是一个2112*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)

1 个答案:

答案 0 :(得分:5)

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

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

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