Eigen SimplicialLLT gives incorrect results when called from multiple threads(从多个线程调用Eigen SimplicialLLT时,结果不正确)
问题描述
我正在尝试使用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_lt[IROW]的结果在这两种方法之间是不同的。不知道subProg1中kmat_llt的声明是否有错误。如有任何帮助,我们不胜感激。
推荐答案
您的问题实际上可能与计算无关。它与std::cout一起使用。C++流只在一次调用中是线程安全的。您的所有线程都试图同时写入cout,并开始彼此绊倒,可能会完成彼此的行。有两个简单的解决方案:
- 将屏幕上应该一起显示的所有内容(即整行)放在一个打印文件中。
- 首先将所有内容放入std::ostrgstream中,然后在一次操作中将ostrgstream写入cout。
在C++20中,您可以改用同步输出流。 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0053r0.html
这篇关于从多个线程调用Eigen SimplicialLLT时,结果不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:从多个线程调用Eigen SimplicialLLT时,结果不正确
基础教程推荐
- 非静态 const 成员,不能使用默认赋值运算符 2022-10-09
- CString 到 char* 2021-01-01
- 通过引用传递 C++ 迭代器有什么问题? 2022-01-01
- 如果我为无符号变量分配负值会发生什么? 2022-01-01
- 为什么 RegOpenKeyEx() 在 Vista 64 位上返回错误代码 2021-01-01
- 为什么派生模板类不能访问基模板类的标识符? 2021-01-01
- GDB 显示调用堆栈上函数地址的当前编译二进制文 2022-09-05
- 初始化列表*参数*评估顺序 2021-01-01
- 为什么 typeid.name() 使用 GCC 返回奇怪的字符以及如 2022-09-16
- 我应该对 C++ 中的成员变量和函数参数使用相同的名称吗? 2021-01-01
