使用OpenMP和Eigen会导致无限循环/死锁
Using OpenMP and Eigen causes infinite loop/deadlock
我正在解决一个更大的问题,当我试图使用OpenMP并行化一些循环时,遇到了一个错误。我在下面用一些更简单的代码重现了这个问题,这些代码模仿了我自己的代码。
问题是,当我运行程序时,它会随机进入某种无限循环/死锁(CPU是100%,但什么都不做)。从我的测试中可以看出,其中一个线程试图计算矩阵矩阵乘积,但由于某种原因从未完成。
我知道,如果启用OpenMP,Eigen将使用OpenMP并行化矩阵矩阵产品。除此之外,我还添加了另一个并行循环。然而,如果我通过定义Eigen_DONT_PARALLELIZE来禁用Eigen的并行化,那么这个错误仍然会发生。
我在MacOS 10.6.8和Eigen 3.0.4上使用的是gcc版本4.6.0 20101127。
我不知道出了什么问题。。。
#include <iostream>
#include <Eigen/Core>
using namespace std;
using namespace Eigen;
MatrixXd Test(MatrixXd const& F, MatrixXd const& G)
{
MatrixXd H(F.rows(), G.cols());
H.noalias() = F*G;
return H;
}
int main()
{
MatrixXd F = MatrixXd::Random(2,2);
MatrixXd G = MatrixXd::Random(2,2);
#pragma omp parallel for
for (unsigned int i = 0; i < 10000; ++i)
MatrixXd H = Test(F,G);
cout << "Done!" << endl;
}
经过一些调试,我认为问题位于Eigen中。在文件src/Core/products/GeneralBlockPanelKernel.h
中,有一个名为manage_caching_sizes
的函数,它声明了两个静态变量:
static std::ptrdiff_t m_l1CacheSize = 0;
static std::ptrdiff_t m_l2CacheSize = 0;
将其更改为:
static std::ptrdiff_t m_l1CacheSize = 0;
static std::ptrdiff_t m_l2CacheSize = 0;
#pragma omp threadprivate(m_l1CacheSize, m_l2CacheSize)
解决了我的问题。
即使是最新版本的Eigen(3.0.5),我也遇到了同样的问题。我尝试了上面提出的修复方法,但3.0.5版本不可能,因为有新的初始化程序。所以我做了以下改变:
static std::ptrdiff_t m_l1CacheSize;
static std::ptrdiff_t m_l2CacheSize;
#pragma omp threadprivate(m_l1CacheSize, m_l2CacheSize)
if (m_l1CacheSize==0)
{
m_l1CacheSize = manage_caching_sizes_second_if_negative(queryL1CacheSize(),8 * 1024);
m_l2CacheSize = manage_caching_sizes_second_if_negative(queryTopLevelCacheSize(),1*1024*1024);
}
解决了我的问题。
我在使用Microsoft Visual Studio 2010 SP1 PPL/parallel_fo时遇到了同样的问题。中描述了解决方案
http://eigen.tuxfamily.org/dox/TopicMultiThreading.html
在多线程应用中使用Eigen
如果您自己的应用程序是多线程的,并且线程调用Eigen,然后必须通过在创建线程之前调用以下例程:
#include <Eigen/Core> int main(int argc, char** argv) { Eigen::initParallel(); ... }
在应用程序与OpenMP并行的情况下,您可能想要禁用Eigen自己的并行化,如前所述部分
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 过载'operator new'如何导致无限循环?
- 如何在没有死锁和/或争用的情况下正确使用 std::mutex C++?
- C++正则表达式无限循环
- 程序在尝试猜测它选择的随机数时进入无限循环?
- 用C++中的std::condition_variable将线程置于死锁中会有风险吗
- 遍历链表时的无限循环
- 使用 std::async 时死锁,将来作为成员
- 如何调试读写器锁的死锁?
- 循环链表:无限循环
- 比较两个字符串后卡在无限循环中
- 在做一段时间内检查字符的无限循环
- 逐字读取文本文件中的每一行并转换为 int(无限循环或崩溃?
- 在这个无限循环中,当输入 0 时终止,当输入 int 范围之外的任何内容时,程序行为不正常
- 可能的无限循环
- 超出 int 的值范围后的无限循环
- 为什么这段代码会导致无限循环?
- C++中的循环类型依赖项死锁
- boost::thread应该在无限循环中运行,并等待没有互斥锁的新输入
- 使用OpenMP和Eigen会导致无限循环/死锁