multithreading - 特征,并行 ConjugateGradient 失败:更多线程,更多成本
问题描述
我想在 Eigen 3.3.7 ( gitlab ) 中使用并行 ConjugateGradient 来解决 Ax=b,但它表明更多的线程,更多的计算成本。我测试了这个问题中的代码,并将矩阵维度从 90000 更改为 9000000。这是代码(我将文件命名为 test-cg-parallel.cpp):
// Use RowMajor to make use of multi-threading
typedef SparseMatrix<double, RowMajor> SpMat;
typedef Triplet<double> T;
// Assemble sparse matrix from
// https://eigen.tuxfamily.org/dox/TutorialSparse_example_details.html
void insertCoefficient(int id, int i, int j, double w, vector<T>& coeffs,
VectorXd& b, const VectorXd& boundary)
{
int n = int(boundary.size());
int id1 = i+j*n;
if(i==-1 || i==n) b(id) -= w * boundary(j); // constrained coefficient
else if(j==-1 || j==n) b(id) -= w * boundary(i); // constrained coefficient
else coeffs.push_back(T(id,id1,w)); // unknown coefficient
}
void buildProblem(vector<T>& coefficients, VectorXd& b, int n)
{
b.setZero();
ArrayXd boundary = ArrayXd::LinSpaced(n, 0,M_PI).sin().pow(2);
for(int j=0; j<n; ++j)
{
for(int i=0; i<n; ++i)
{
int id = i+j*n;
insertCoefficient(id, i-1,j, -1, coefficients, b, boundary);
insertCoefficient(id, i+1,j, -1, coefficients, b, boundary);
insertCoefficient(id, i,j-1, -1, coefficients, b, boundary);
insertCoefficient(id, i,j+1, -1, coefficients, b, boundary);
insertCoefficient(id, i,j, 4, coefficients, b, boundary);
}
}
}
int main()
{
int n = 3000; // size of the image
int m = n*n; // number of unknowns (=number of pixels)
// Assembly:
vector<T> coefficients; // list of non-zeros coefficients
VectorXd b(m); // the right hand side-vector resulting from the constraints
buildProblem(coefficients, b, n);
SpMat A(m,m);
A.setFromTriplets(coefficients.begin(), coefficients.end());
// Solving:
// Use ConjugateGradient with Lower|Upper as the UpLo template parameter to make use of multi-threading
clock_t time_start, time_end;
time_start=clock();
ConjugateGradient<SpMat, Lower|Upper> solver(A);
VectorXd x = solver.solve(b); // use the factorization to solve for the given right hand side
time_end=clock();
cout<<"time use:"<<1000*(time_end-time_start)/(double)CLOCKS_PER_SEC<<"ms"<<endl;
return 0;
}
我用gcc 7.4.0编译代码,6核(12线程)Intel Xeon E2186G CPU,编译运行细节如下:
liu@liu-Precision-3630-Tower:~/test$ g++ test-cg-parallel.cpp -O3 -fopenmp -o cg
liu@liu-Precision-3630-Tower:~/test$ OMP_NUM_THREADS=1 ./cg
time use:747563ms
liu@liu-Precision-3630-Tower:~/test$ OMP_NUM_THREADS=4 ./cg
time use: 1.49821e+06ms
liu@liu-Precision-3630-Tower:~/test$ OMP_NUM_THREADS=8 ./cg
time use: 2.60207e+06ms
谁能给我一些建议?非常感谢。
解决方案
推荐阅读
- web - 如何在 Web 逻辑服务器上安装 .crt 文件(SSL)?
- symfony - Doctrine SQL Query Order By ASC NULL Last
- angular - 捕获错误并返回 of(undefined) 会停止流(Angular 7,rxjs6)
- python - 计算后如何只打印总数?
- c# - C# 数组在哪里存储其元数据?
- php - 如果产品在 Woocommerce 的购物车中,请删除添加到购物车按钮
- java - 是否可以嵌套 Hazelcast JET 管道,以便内部管道可以计算外部管道的结果?
- python - Python Dict:获取与键列表关联的值,其中每个后续键驻留在前一个键的值中
- python - 如何使用 .corr() Pearson Correlation 获取 DataFrame 中两个选定列之间的相关性
- c++ - C++ 智能指针在 std::make_unique 中丢失