OpenMP では、その配列の個別の要素に並列に書き込むことができますか? 簡単なテスト プログラムを次に示します。
#include <stdio.h>
#include <math.h>
int main(){
const int n=100;
int squares[n];
// Can we write to distinct array elements simultaneously?
// Valgrind+DRD doesn't like this.
#pragma omp parallel for
for(int i=0; i<n; i++)
squares[i]=i*i;
// We definitely can read from distinct array elements simultaneously.
int sumOfSquares=0;
#pragma omp parallel for reduction(+:sumOfSquares)
for(int i=0; i<n; i++)
sumOfSquares+=squares[i];
// The result always seems to be correct.
printf("sumOfSquares = %d = %d\n", sumOfSquares, n*(n-1)*(2*n-1)/6);
}
上記のコードを でコンパイルし、 でgcc -std=c99 -fopenmp -g openmp_arrays.c
スレッド セーフをチェックしましvalgrind --tool=drd --check-stack-var=yes --read-var-info=yes --dsymutil=yes a.out
た。プログラムは常に正しい結果を返すように見えますが、Valgrind はエラーを返します:
==18064== drd, a thread error detector
==18064== Copyright (C) 2006-2011, and GNU GPL'd, by Bart Van Assche.
==18064== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==18064== Command: a.out
==18064==
==18064== Thread 2:
==18064== Conflicting load by thread 2 at 0x7ff000730 size 8
==18064== at 0x4008B0: main._omp_fn.1 (openmp_arrays.c:16)
==18064== by 0x4E45EE9: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==18064== by 0x4C2D9E1: ??? (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
==18064== by 0x5053E99: start_thread (pthread_create.c:308)
==18064== by 0x535CCCC: clone (clone.S:112)
==18064== Allocation context: unknown.
==18064== Other segment start (thread 1)
==18064== at 0x4C2DF29: pthread_create@* (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
==18064== by 0x4E4631B: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==18064== by 0x40075E: main (openmp_arrays.c:10)
==18064== Other segment end (thread 1)
==18064== at 0x4E47591: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==18064== by 0x4E466ED: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==18064== by 0x4007B1: main (openmp_arrays.c:16)
==18064==
==18064== Conflicting load by thread 2 at 0x7ff000738 size 4
==18064== at 0x4008BB: main._omp_fn.1 (openmp_arrays.c:16)
==18064== by 0x4E45EE9: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==18064== by 0x4C2D9E1: ??? (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
==18064== by 0x5053E99: start_thread (pthread_create.c:308)
==18064== by 0x535CCCC: clone (clone.S:112)
==18064== Allocation context: unknown.
==18064== Other segment start (thread 1)
==18064== at 0x4C2DF29: pthread_create@* (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
==18064== by 0x4E4631B: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==18064== by 0x40075E: main (openmp_arrays.c:10)
==18064== Other segment end (thread 1)
==18064== at 0x4E47591: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==18064== by 0x4E466ED: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==18064== by 0x4007B1: main (openmp_arrays.c:16)
==18064==
==18064== Conflicting load by thread 2 at 0x7ff00073c size 4
==18064== at 0x40092B: main._omp_fn.1 (openmp_arrays.c:16)
==18064== by 0x4E45EE9: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==18064== by 0x4C2D9E1: ??? (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
==18064== by 0x5053E99: start_thread (pthread_create.c:308)
==18064== by 0x535CCCC: clone (clone.S:112)
==18064== Allocation context: unknown.
==18064== Other segment start (thread 1)
==18064== at 0x4C2DF29: pthread_create@* (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
==18064== by 0x4E4631B: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==18064== by 0x40075E: main (openmp_arrays.c:10)
==18064== Other segment end (thread 1)
==18064== at 0x4E47591: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==18064== by 0x4E466ED: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==18064== by 0x4007B1: main (openmp_arrays.c:16)
==18064==
==18064==
==18064== For counts of detected and suppressed errors, rerun with: -v
==18064== ERROR SUMMARY: 4 errors from 3 contexts (suppressed: 600066 from 59)