编辑:我的第一个代码示例错了。用更简单的方法修复。
我为大型矢量和矩阵之间的代数运算实现了一个C ++库。 我发现在x86-x64 CPU上,OpenMP并行向量添加,点积等不会比单线程更快。 并行操作比单线程快-1%-6%。 这是因为内存带宽限制(我认为)。
所以,问题是,这样的代码是否有真正的性能优势:
void DenseMatrix::identity()
{
assert(height == width);
size_t i = 0;
#pragma omp parallel for if (height > OPENMP_BREAK2)
for(unsigned int y = 0; y < height; y++)
for(unsigned int x = 0; x < width; x++, i++)
elements[i] = x == y ? 1 : 0;
}
在此示例中,使用OpenMP没有严重的缺点。 但是,如果我正在使用稀疏向量和稀疏矩阵的OpenMP,我不能使用例如* .push_back(),在这种情况下,问题变得严重。 (稀疏向量的元素不像密集向量那样连续,因此并行编程有一个缺点,因为结果元素可以随时到达 - 而不是从较低到较高的索引)
答案 0 :(得分:1)
我不认为这是内存带宽问题。我清楚地看到r
上存在问题:从多个线程访问r
,这会导致数据竞争和虚假共享。虚假分享可能会严重损害您的表现。
我想知道你是否能得到正确答案,因为r
上有数据竞赛。你得到了正确的答案吗?
但是,解决方案非常简单。在r
上执行的操作是 reduction ,可以通过OpenMP的reduction
子句轻松实现。
尝试在reduction(+ : r)
后添加#pragma omp parallel
。
(注意:double
上的添加不是可交换和关联的。您可能会看到一些精度错误,或者与序列代码的结果有所不同。)