我想并行化以下代码
for (i=0; i<M; i++){
temp = 0.
for (j=0; j<N; j++){
temp += A[i][j]*v[j];
u[i] = temp;
}
其中u [i]可以独立计算。所以我试着做了
#pragma omp parallel for private (j,temp)
for (i=0; i<M; i++){
temp = 0.
for (j=0; j<N; j++){
temp += A[i][j]*v[j];
u[i] = temp;
}
我发现第二种情况比第一种情况慢。知道为什么会这样吗?这里M~100和N~2。
答案 0 :(得分:0)
并行化并没有任何好处,因为数据非常小:设置和协调并行计算的开销超过了并行执行的任何好处。
此外,计算很容易优化。
您的编译器肯定会展开内部循环(其中N = 2),因此它变为:
u[i] = A[i][0]*v[0] + A[i][1] * v[1]
即使我们假设A是64位类型(如double),那么i上的外环可以展开4次,这样每次访问A都会使用一个64字节的缓存行(对于8个条目A [i] ] [0]到A [i + 3] [1])。
结果是一个只有25次迭代的循环(对于M = 100):
for (i=0; i<M; i+= 4)
{
u[i] = A[i][0]*v[0] + A[i][1] * v[1];
u[i+1] = A[i+1][0]*v[0] + A[i+1][1] * v[1];
u[i+2] = A[i+2][0]*v[0] + A[i+2][1] * v[1];
u[i+3] = A[i+3][0]*v[0] + A[i+3][1] * v[1];
}
通过预取,所有访问基本上都已在缓存中。
您需要更大的数据才能看到并行化的好处:)