並列領域内でのクリティカルの使用に関して、OpenMP の理解が著しく不足しているようです。私の質問は簡単です: 以下のコードが valgrind drd で警告を生成するのはなぜですか?
#include <stdio.h>
#include <unistd.h>
void A(int* a)
{
printf("a++\n");
(*a)++;
}
void B(int* a)
{
printf("a--\n");
(*a)--;
}
void f(int* a)
{
#pragma omp critical
A(a);
sleep(1); /* work done here */
#pragma omp critical
B(a);
}
int main(int argc, char** argv)
{
int i;
int a = 0;
#pragma omp parallel for
for(i = 0; i < 4; ++i)
{
f(&a);
}
return 0;
}
次のようにコンパイルされます。
gcc -fopenmp -g -o omptest omptest.c
そして、valgrind 呼び出しは
valgrind --tool=drd --check-stack-var=yes ./omptest
私の理解では、クリティカルセクションは、まさに私が受け取る警告から私を保護する必要があるということでした. エラーを把握するために2日間費やしていますが、見つかりません。誰かが私が正確に理解していなかったことにヒントを与えることができれば、とてもうれしいです.
どんな助けでも大歓迎です。
編集: 私の2 CPUマシンでの(繰り返しの)警告は次のとおりです。
Thread 2:
Conflicting load by thread 2 at 0x7fefffecc size 4
at 0x4007DE: A (omptest.c:7)
by 0x40082E: f (omptest.c:19)
by 0x400902: main._omp_fn.0 (omptest.c:35)
by 0x4E45EE9: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
by 0x4C2D9E1: ??? (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
by 0x5053E99: start_thread (pthread_create.c:308)
by 0x535B39C: clone (clone.S:112)
Allocation context: unknown.
Other segment start (thread 1)
at 0x4C2DF29: pthread_create@* (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
by 0x4E4631B: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
by 0x400889: main (omptest.c:32)
Other segment end (thread 1)
at 0x5326F1D: ??? (syscall-template.S:82)
by 0x5326DBB: sleep (sleep.c:138)
by 0x40083D: f (omptest.c:21)
by 0x400902: main._omp_fn.0 (omptest.c:35)
by 0x400895: main (omptest.c:32)
Conflicting store by thread 2 at 0x7fefffecc size 4
at 0x4007E7: A (omptest.c:7)
by 0x40082E: f (omptest.c:19)
by 0x400902: main._omp_fn.0 (omptest.c:35)
by 0x4E45EE9: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
by 0x4C2D9E1: ??? (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
by 0x5053E99: start_thread (pthread_create.c:308)
by 0x535B39C: clone (clone.S:112)
Allocation context: unknown.
Other segment start (thread 1)
at 0x4C2DF29: pthread_create@* (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
by 0x4E4631B: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
by 0x400889: main (omptest.c:32)
Other segment end (thread 1)
at 0x5326F1D: ??? (syscall-template.S:82)
by 0x5326DBB: sleep (sleep.c:138)
by 0x40083D: f (omptest.c:21)
by 0x400902: main._omp_fn.0 (omptest.c:35)
by 0x400895: main (omptest.c:32)
Thread 1:
Conflicting load by thread 1 at 0x7fefffecc size 4
at 0x400805: B (omptest.c:13)
by 0x40084E: f (omptest.c:24)
by 0x400902: main._omp_fn.0 (omptest.c:35)
by 0x400895: main (omptest.c:32)
Allocation context: unknown.
Other segment start (thread 2)
at 0x535B361: clone (clone.S:84)
Other segment end (thread 2)
at 0x5326F1D: ??? (syscall-template.S:82)
by 0x5326DBB: sleep (sleep.c:138)
by 0x40083D: f (omptest.c:21)
by 0x400902: main._omp_fn.0 (omptest.c:35)
by 0x4E45EE9: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
by 0x4C2D9E1: ??? (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
by 0x5053E99: start_thread (pthread_create.c:308)
by 0x535B39C: clone (clone.S:112)
Conflicting store by thread 1 at 0x7fefffecc size 4
at 0x40080E: B (omptest.c:13)
by 0x40084E: f (omptest.c:24)
by 0x400902: main._omp_fn.0 (omptest.c:35)
by 0x400895: main (omptest.c:32)
Allocation context: unknown.
Other segment start (thread 2)
at 0x535B361: clone (clone.S:84)
Other segment end (thread 2)
at 0x5326F1D: ??? (syscall-template.S:82)
by 0x5326DBB: sleep (sleep.c:138)
by 0x40083D: f (omptest.c:21)
by 0x400902: main._omp_fn.0 (omptest.c:35)
by 0x4E45EE9: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
by 0x4C2D9E1: ??? (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
by 0x5053E99: start_thread (pthread_create.c:308)
by 0x535B39C: clone (clone.S:112)
a のデータ競合としての警告を理解しています。7 行目と 13 行目は (*a)-- と (*a)++ 呼び出しです。