2012-01-11 41 views
10

我正在解決一個更大的問題,並且在嘗試使用OpenMP並行化一些循環時遇到了一個錯誤。我用一些比較簡單的代碼來模仿我自己的代碼。使用OpenMP和Eigen導致無限循環/死鎖

問題是,當我運行程序時,它會隨機進入某種無限循環/死鎖(CPU是100%,但什麼都不做)。從我的測試中可以看出,其中一個線程嘗試計算矩陣 - 矩陣乘積,但由於某種原因而未能完成。

我知道如果啓用OpenMP,Eigen將使用OpenMP並行化矩陣矩陣產品。除此之外,我還添加了另一個並行循環。但是,如果我通過定義EIGEN_DONT_PARALLELIZE來禁用Eigen的並行化,該錯誤仍然會發生。

我在使用Eigen 3.0.4的MacOS 10.6.8上使用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; 
} 
+0

'MatrixXd :: Random'是線程安全的嗎? – Mysticial 2012-01-12 00:00:23

+0

在我的真實代碼中,我沒有調用MatrixXd :: Random。編輯:我改變了代碼以去除對MatrixXd :: Random的調用,並且該bug仍然存在。 – user1144371 2012-01-12 00:01:18

+0

它不是像[this]這樣的笨蛋(http://eigen.tuxfamily.org/dox/TopicWrongStackAlignment.html)?因爲目前這看起來不像openmp錯誤。我下載並運行你的程序並沒有任何問題與海灣合作委員會版本4.5.0 20100604。 – Bort 2012-01-12 10:13:27

回答

10

一些調試後,我認爲這個問題是位於艾根。在文件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) 

固定我的問題。

+2

我剛剛注意到這個bug在最近的Eigen版本中得到修復,這要感謝這個stackoverflow問題,請參閱bugreport:http://eigen.tuxfamily.org/bz/show_bug.cgi?id=406所以現在解決方案將是更新您的Eigen庫。 – catchmeifyoutry 2012-02-14 16:23:45

2

即使使用最新版本的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); 
} 

解決了我的問題。

2

我在使用Microsoft Visual Studio 2010 SP1 PPL/parallel_for時遇到同樣的問題。該解決方案在

http://eigen.tuxfamily.org/dox/TopicMultiThreading.html

中描述了多線程應用程序

在這種情況下你自己的多線程應用程序使用本徵和多線程 做出徵電話,那麼你必須通過 初始化徵在創建線程之前調用下面的程序:

#include <Eigen/Core> 

int main(int argc, char** argv) 
{ 
    Eigen::initParallel(); 

    ... 
} 

在如果您的應用程序與OpenMP並行處理,您可能想要禁用Eigen自己的parallization,如前面的 部分所述。