【发布时间】:2021-12-12 04:52:41
【问题描述】:
我正在尝试使用 SimplicialLLT 来计算 SparseMatrix。由于我的程序在循环中运行并且每个稀疏矩阵都不同,我试图并行化对 SimplicialLLT 的调用,如下所示。这不是确切的运行代码。我试图复制进行调用的部分。
#include <iostream>
#include <cstdlib>
#include "Eigen/Core"
#include "Eigen/LU"
#include "Eigen/Sparse"
#include "Eigen/StdVector"
#include <thread>
#include <mutex>
#define NROW 4
void subProg1(int ii, int nodes);
using namespace std;
int main()
{
int imax = 4;
int ii, nodes;
std::thread threadpointer[4];
nodes = 20000;
for (ii=0;ii<imax;ii++) {
threadpointer[ii] = std::thread(subProg1,ii,nodes);
//threadpointer[ii].join();
}
for (ii=0;ii<imax;ii++) {
threadpointer[ii].join();
}
}
void subProg1(int IROW, int nodes)
{
static vector<SparseMatrix<double>> Kmat(NROW, SparseMatrix<double> (nodes*3,nodes*3));
static vector<SimplicialLLT<SparseMatrix<double>>> Kmat_LLT(Kmat.size());
//Asign Kmat values here
//Kmat[IROW] = ....
//Invert Kmat using SimplicialLLT
cout<< " Before Kmat_LLT IROW :" <<IROW<<endl;
Kmat_LLT[IROW].compute(Kmat[IROW]);
cout<< " After Kmat_LLT IROW:" <<IROW<<endl;
}
在调用 subProg1 后立即加入线程时得到的结果与在对 subProg1 的所有调用之后将线程加入单独的循环中时不同。我试图确定为什么会这样。 cout 语句显示如下
当线程在调用后立即加入时(本质上这是在没有多线程的情况下运行)
before Kmat_LLT IROW: 0
after Kmat_LLT IROW: 0
before Kmat_LLT IROW: 1
after Kmat_LLT IROW: 1
before Kmat_LLT IROW: 2
after Kmat_LLT IROW: 2
before Kmat_LLT IROW: 3
after Kmat_LLT IROW: 3
当 subProg1 作为多线程的一部分被调用并在所有调用完成后加入时
before Kmat_LLT IROW : 3
before Kmat_LLT IROW: 0
before Kmat_LLT IROW: 1
before Kmat_LLT IROW: 2
after Kmat_LLT IROW : 2
after Kmat_LLT IROW: 0
after Kmat_LLT IROW: 1
after Kmat_LLT IROW: 3
我不确定为什么 Kmat_LLT[IROW] 的结果在两种方法之间不同。想知道 subProg1 中 Kmat_LLT 的声明是否有问题。任何帮助表示赞赏。
【问题讨论】:
-
想知道是否有人对这里可能出现的问题有任何想法。不确定是否应该以不同的方式声明 simplicialLLT
-
如果有人能帮我解决这个请求,我将不胜感激。
-
你用的是什么编译器?您对结果使用静态变量。这些在函数第一次运行时被初始化。那是在其中一个线程内。根据编译器的不同,这可能对竞争条件不安全。
-
@Homer512 我正在使用 VS2017。虽然我使用静态数组来存储结果,但它们基于 IROW,对于 subProg1 的每个调用(线程)都是唯一的。我的理解是这不会导致竞争条件。
标签: c++ multithreading eigen