5

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)
4

1 に答える 1

5

You definitely can write to distinct elements, and your example is correct. You can have a look at the DRD documentation which provides a more elaborate example

http://valgrind.org/docs/manual/drd-manual.html#drd-manual.openmp

Btw, this documentation specifies that "for most Linux distributions (...) you will have to recompile GCC" to use DRD and provides the path to the dedicated script. This might explain your problem in case you skipped this step.

于 2013-09-20T14:29:53.940 に答える