我一直在尝试在具有2个CPU的系统上测试我的复杂CSR矩阵向量代码,每个CPU有6个核心。令人惊讶的是,我获得了1,2,4,6或12个线程几乎相同的时间。它工作,我可以看到相应的线程在乘法过程中是活着的,但没有加速。我不明白我是否犯了一些错误,或者只是手头的问题无法缩放。
void spmv_csr(int num_rows, const int* rowPtrs, const int* colIdxs, const double complex* values, const double complex* x, double complex* y)
{
double complex rowSum;
int i, j, row_start, row_end;
clock_t begin, end;
begin = clock();
#pragma omp parallel for private(j, i, row_start, row_end) reduction(+:rowSum)
for(i = 0; i < num_rows; i++)
{
rowSum = 0.00 + 0.00 *I;
row_start = rowPtrs[i]-1;
row_end = rowPtrs[i+1]-1;
for (j=row_start; j<row_end; j++)
{
rowSum += ((creal(values[j]) * creal(x[colIdxs[j]-1])) - (cimag(values[j]) * cimag(x[colIdxs[j]-1]))) + (((creal(values[j]) * cimag(x[colIdxs[j]-1])) + (cimag(values[j]) * creal(x[colIdxs[j]-1]))) * I);
}
y[offset+i] = rowSum;
}
end = clock();
printf("Time Elapsed: %f seconds\n", (double)(end - begin)/CLOCKS_PER_SEC);
}
我用1,2,4,6,8,12个线程运行大约0.38秒,我不明白为什么我甚至没有看到10%的加速。
提前感谢任何意见。
答案 0 :(得分:1)
看起来缩减变量rowSum正在成为序列化的一个点。由于rowSum不仅累积为总数而且还从(y [offset + i] = rowSum;)读取,因此必须进行序列化。
如果您希望rowSum只跨越一行,我会删除缩减并将其设为私有。我会将编译指示改为:
#pragma omp parallel for private(j, i, row_start, row_end, rowSum)
如果你想让rowSum成为所有行的总数,我会使用我的上述建议来获得并行性,然后使用prefix-sum来修改y以获得正确的总数。