【发布时间】:2020-07-30 13:29:24
【问题描述】:
我编写了一个 C++ 代码来求解线性系统 A.x = b,其中 A 是一个对称矩阵,首先使用 LAPACK(E) 对矩阵 A = V.D.V^T 进行对角化(因为我稍后需要特征值),然后求解 @987654324 @ 当然V 是正交的。
现在我想尽可能优化最后一个操作,例如通过使用 (C)BLAS 例程和 OpenMP。
这是我的幼稚实现:
// Solve linear system A.X = B for X (V contains eigenvectors and D eigenvalues of A)
void solve(const double* V, const double* D, const double* B, double* X, const int& N)
{
#ifdef _OPENMP
#pragma omp parallel for
#endif
for (int i=0; i<N; i++)
{
for (int j=0; j<N; j++)
{
for (int k=0; k<N; k++)
{
X[i] += B[j] * V[i+k*N] * V[j+k*N] / D[k];
}
}
}
}
所有数组都是 C 样式的数组,其中 V 的大小为 N^2,D 的大小为 N,B 的大小为 N,X 的大小为 @987654334 @(并用零初始化)。
目前,这种幼稚的实现非常缓慢,是代码的瓶颈。任何提示和帮助将不胜感激!
谢谢
编辑 感谢 Jérôme Richard 的回答和评论,我通过调用 BLAS 并使用 OpenMP 并行化中间循环进一步优化了他的解决方案。在 1000x1000 矩阵上,这个解决方案比他的命题快约 4 倍,它本身比我的幼稚实现快 1000 倍。
对于N=1000 和N=2000,我发现#pragma omp parallel for simd 子句在两台分别具有 4 核和 20 核的不同机器上比其他替代方案更快。
void solve(const double* V, const double* D, const double* B, double* X, const int& N)
{
double* sum = new double[N]{0.};
cblas_dgemv(CblasColMajor,CblasTrans,N,N,1.,V,N,B,1,0.,sum,1);
#pragma omp parallel for simd
for (int i=0; i<N; ++i)
{
sum[i] /= D[i];
}
cblas_dgemv(CblasColMajor,CblasNoTrans,N,N,1.,V,N,sum,1,0.,X,1);
delete [] sum;
}
【问题讨论】:
标签: c++ performance matrix blas