我正在使用英特尔编译器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。
计时器:使用POSIX times()API返回值diff。 (它使用挂钟进行并发,我做了检查)
E5主题1 SIMD需要:291.520000(s)
答案 0 :(得分:5)
如果sSize
= 129,就像编辑中那样,那么并行化循环的开销并不会带来回报。如果您向我们展示顺序实现(无SIMD)和纯并行实现(即使用#pragma omp parallel for
但没有SIMD)的数量,这将更容易确认。
可能发生的事情是即使纯粹的并行版本也比顺序版本慢。当您为最外层循环的每次迭代启动/创建并行区域时,不仅会减小循环大小。
至于SIMD版本,这个问题基本上是针对这个问题量身定制的:你有一个高度可矢量化的内核,它太小而不能在线程之间分配。