1

次のコードで valgrind による競合状態が発生するのはなぜですか?

#include <iostream>
#include <ctime>
#include <tr1/random>
#include <omp.h>

using namespace std;

tr1::mt19937 randgen;

int random(int min, int max)
{
    int number;
    if (min!=max)
    {
        #pragma omp critical(randgen)
        number = ((randgen() % (max - min)) + min);
        return number;

    } else
        return min;
}

int main(int argc, char *argv[])
{
    omp_set_num_threads(4);
    randgen.seed(time(NULL));
    #pragma omp parallel for
    for (int i = 0; i < 10; i++)
    {
        random(10,100);
    }

    return 0;
}

次のようにコンパイル:

g++ -O3 -g -Wall -c -fmessage-length=0 -fopenmp -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.cpp"
g++  -o "test"  ./main.o   -lgomp

Valgrindの結果

valgrind --tool=drd --check-stack-var=yes --read-var-info=yes ./test
==19561== drd, a thread error detector
==19561== Copyright (C) 2006-2010, and GNU GPL'd, by Bart Van Assche.
==19561== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info
==19561== Command: ./test
==19561== 
==19561== Thread 3:
==19561== Conflicting load by thread 3 at 0x00603420 size 4
==19561==    at 0x400A10:     _ZNSt3tr116mersenne_twisterImLi32ELi624ELi397ELi31ELm2567483615ELi11ELi7ELm2636928640ELi15E    Lm4022730752ELi18EEclEv.constprop.2 (random.tcc:323)
==19561==    by 0x400BB9: main._omp_fn.0 (main.cpp:16)
==19561==    by 0x4E3FEC9: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==19561==    by 0x4C2A803: vgDrd_thread_wrapper (drd_pthread_intercepts.c:281)
==19561==    by 0x58FDEFB: start_thread (pthread_create.c:304)
==19561==    by 0x543059C: clone (clone.S:112)
==19561== Location 0x603420 is 0 bytes inside randgen._M_p,
==19561== a global variable declared at main.cpp:8
==19561== Other segment start (thread 1)
==19561==    at 0x4C2AE7D: pthread_create@* (drd_pthread_intercepts.c:440)
==19561==    by 0x4E402FB: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==19561==    by 0x400898: main (main.cpp:27)
==19561== Other segment end (thread 1)
==19561==    at 0x4E41550: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==19561==    by 0x4E406CD: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==19561==    by 0x4008A4: main (main.cpp:27)

#pragma omp critical を使用すると、一度に 1 つのスレッドだけが特定の関数を呼び出すことができると思いましたか? よくわかりません。

4

1 に答える 1

1

Valgrind マニュアルで答えを見つけることができます。

DRD は、このオプション [--disable-linux-futex] で構成され、シンボル情報が存在する libgomp ライブラリのみをサポートします。ほとんどの Linux ディストリビューションでは、これは GCC を再コンパイルする必要があることを意味します。

于 2012-04-26T00:16:11.200 に答える