2012-01-11 4 views
10

Sto risolvendo un problema molto più grande e ho riscontrato un errore quando tento di utilizzare OpenMP per parallelizzare alcuni loop. Ho riprodotto il problema con un codice più semplice di seguito che riproduce il mio codice.L'utilizzo di OpenMP ed Eigen causa loop/deadlock infiniti

Il problema è che quando eseguo il programma, casualmente entrerà in una sorta di loop infinito/deadlock (la CPU è al 100%, ma non fa nulla). Da quello che posso dire dai miei test, uno dei thread tenta di calcolare il prodotto matrix-matrix ma non finisce mai per qualche motivo.

So che se si attiva OpenMP, Eigen eseguirà il parallelismo dei prodotti matrice-matrice utilizzando OpenMP. Sto anche aggiungendo un altro ciclo parallelo al di fuori di questo. Tuttavia, questo errore si verifica ancora se disattivo la parallelizzazione di Eigen definendo EIGEN_DONT_PARALLELIZE.

Sto utilizzando gcc versione 4.6.0 20101127 su MacOS 10.6.8 con Eigen 3.0.4.

io non riesco a capire che cosa potrebbe andare male ...

#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' thread-safe? – Mysticial

+0

Nel mio codice reale, non sto chiamando MatrixXd :: Random. Modifica: ho cambiato il codice per rimuovere le chiamate a MatrixXd :: Random e il bug è ancora lì. – user1144371

+0

non è qualcosa di stupido come [questo] (http://eigen.tuxfamily.org/dox/TopicWrongStackAlignment.html)? Perché attualmente questo non sembra un errore di openmp. Ho scaricato ed eseguito il tuo programma in parallelo senza problemi con gcc versione 4.5.0 20100604. – Bort

risposta

10

Dopo un po 'di debug, penso che il problema si trova in Eigen. Nel file src/Core/products/GeneralBlockPanelKernel.h c'è una funzione chiamata manage_caching_sizes che dichiara due variabili statiche:

static std::ptrdiff_t m_l1CacheSize = 0; 
static std::ptrdiff_t m_l2CacheSize = 0; 

Cambiare questo per:

static std::ptrdiff_t m_l1CacheSize = 0; 
static std::ptrdiff_t m_l2CacheSize = 0; 
#pragma omp threadprivate(m_l1CacheSize, m_l2CacheSize) 

fisso il mio problema.

+2

Ho appena notato che questo bug è stato corretto nelle versioni Eigen recenti, grazie a questa domanda StackOverflow, vedere la segnalazione dei bug: http://eigen.tuxfamily.org/bz/show_bug.cgi?id=406 Quindi ora la soluzione sarebbe per aggiornare la tua libreria Eigen. – catchmeifyoutry

2

Ho avuto lo stesso problema, anche con la versione più recente di Eigen (3.0.5). Ho provato la correzione proposta sopra e non è possibile con la versione 3.0.5, a causa dei nuovi inizializzatori. Così ho apportato la seguente modifica:

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); 
} 

risolto il problema.

2

Avevo lo stesso problema utilizzando Microsoft Visual Studio 2010 SP1 PPL/parallel_for. La soluzione è descritta nel

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

Utilizzando Eigen in un'applicazione multithread

Nel caso la propria applicazione è multithreading, e molteplici discussioni effettuare chiamate verso Eigen, poi si deve inizializzare Eigen dal chiamando il seguente procedura prima di creare i thread:

#include <Eigen/Core> 

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

    ... 
} 

In Nel caso in cui l'applicazione sia parallelizzata con OpenMP, è possibile che desideri disabilitare la parallelizzazione di Eigen come descritto nella precedente sezione .