带有 OpenMP 的特征稀疏矩阵 - 插入值时崩溃
Eigen SparseMatrix with OpenMP - crash when inserting values
对于一个非常简单的测试示例,当尝试在 OpenMP 构造中填充Eigen::SparseMatrix
时,应用程序崩溃。
SparseMatrix<double> A_mat( nCol, nRow );
//A_mat.reserve( VectorXi::Constant( nCol, nRow ) ); // When commented crashes
auto numThreads = omp_get_max_threads();
#pragma omp parallel for num_threads( numThreads )
for ( int j = 0; j < nCol; ++j )
{
for ( int i = 0; i < nRow; ++i )
{
if ( i >= j )
{
double val = i * nCol + j;
A_mat.insert( i, j ) = val;
}
}
}
此代码仅在我使用线程时按预期方式运行1
。但是,当使用多个线程运行时,会引发以下错误:
double free or corruption (!prev)
double free or corruption (!prev)
double free or corruption (!prev)
double free or corruption (top)
double free or corruption (!prev)
double free or corruption (out)
当我取消注释以下行时:
A_mat.reserve( VectorXi::Constant( nCol, nRow ) );
然后上面给定的代码块再次产生预期的结果,即使使用多个线程运行也是如此。
有人可以向我解释为什么会发生这种情况吗?
在不进一步研究SparseMatrix
的情况下,当您添加的元素多于容量时,它几乎肯定必须(重新(分配内存。这不是线程安全操作,因此切勿同时向SparseMatrix
添加元素,除非您知道它不会重新分配。即便如此,您也应该检查文档以验证这样做是线程安全的,因为我对此表示怀疑(但也许同时插入到不同的列或行中可能是可以的(。即使不安全,它也可能不会崩溃,而只是做错事(即未定义的行为(。
为了记录,这类似于std::vector
的行为方式。以向量重新分配的方式并发调用push_back
是重新分配的竞争条件,因此是未定义的行为(并且会很快导致您所看到的双重释放(。[当然,插入本身也会有一个竞争条件,对于不同坐标的并发插入,SparseMatrix
可能会也可能不会避免这种情况,但我不会打赌。
相关文章:
- 当回溯以零开始时,如何调试崩溃
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 预处理器:插入结构名称中的前一个行号
- 内联映射初始化的动态atexit析构函数崩溃
- 执行函数时导致崩溃的变量
- 在未初始化映射的情况下,将值插入到映射的映射中
- 如何在c++中只将键插入到bimap的一侧
- 插入号码后C++崩溃
- 为什么这个程序在我插入前2个输入后崩溃
- 带有 OpenMP 的特征稀疏矩阵 - 插入值时崩溃
- 从CSV文件读取时,试图将值插入一个字符串中时崩溃
- QT程序使用插入时会崩溃
- 当我插入元素时,C 优先级队列会崩溃
- 由于#Pragma Pack错误而导致的内存损坏 - std Map损坏 - 插入上崩溃
- 递归插入排序崩溃几乎对于大 n
- 插入排序使我的程序崩溃
- 尝试将节点插入矢量<node>,但程序在push_back时不断崩溃
- CGAL 4.4排列插入(arr,曲线)与某些曲线崩溃
- 插入C++会触发程序消息,然后崩溃