我正在尝试使用C ++中的OpenMP来提高稀疏矩阵向量积的性能。我将稀疏矩阵存储在COO格式中,也就是说,我有一个3个数组的结构,对应于稀疏矩阵的每个非零项。对于struct的每个索引,我可以找到行索引,列索引和非零条目的值。另外,我可以通过
指定函数使用的线程数export OMP_NUM_THREADS=n
其中n是我想要使用的线程数。目前,我的代码如下
void ompMatvec(const Vector& x, Vector& y) const {
std::string envName = "OMP_NUM_THREADS";
std::string thread_count = getenv(envName);
int thread_count2 = atoi(thread_count.c_str());
Vector y2(y.numRows());
size_type k;
#pragma omp parallel num_threads(thread_count2)
#pragma omp for
for (k = 0; k < arrayData.size(); ++k) {
y(rowIndices[k]) += arrayData[k] * x(colIndices[k]);
}
}
然而,当我测量性能时,我发现我的速度不是太高。我将上面的并行化函数与:
进行比较 void matvec(const Vector& x, Vector& y) const {
for (size_type k = 0; k < arrayData.size(); ++k) {
y(rowIndices[k]) += arrayData[k] * x(colIndices[k]);
}
}
我想提一下,我创建了一个带有私有成员函数.numRows()的Vector类,它基本上提供了向量的长度。我也在4核上运行代码。是否存在可以使用OpenMP API提高性能的实施更改?或者它是否受我的程序运行的核心数量的限制?
非常感谢任何和所有建议。谢谢!
更新:尝试避免上述竞争条件:
void ompMatvec(const Vector& x, Vector& y) const {
std::string envName = "OMP_NUM_THREADS";
std::string thread_count = getenv(envName);
int thread_count2 = atoi(thread_count.c_str());
size_type k;
#pragma omp parallel num_threads(thread_count2) \
default(none) private(k)
Vector y2(y.numRows());
#pragma omp for
for (k = 0; k < arrayData.size(); ++k) {
y2(rowIndices[k]) += arrayData[k] * x(colIndices[k]);
}
#pragma omp critical
for(k = 0; k < y.numRows(); ++k){
y(k) += y2(k);
}
}