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时,结果不正确
基础教程推荐
- 什么是T&&(双与号)在 C++11 中是什么意思? 2022-11-04
- C++ 标准:取消引用 NULL 指针以获取引用? 2021-01-01
- 如何定义双括号/双迭代器运算符,类似于向量的向量? 2022-01-01
- 调用std::Package_TASK::Get_Future()时可能出现争用情况 2022-12-17
- 设计字符串本地化的最佳方法 2022-01-01
- C++,'if' 表达式中的变量声明 2021-01-01
- 您如何将 CreateThread 用于属于类成员的函数? 2021-01-01
- 运算符重载的基本规则和习语是什么? 2022-10-31
- C++ 程序在执行 std::string 分配时总是崩溃 2022-01-01
- 如何在 C++ 中处理或避免堆栈溢出 2022-01-01