Domanda

Analyzing my C++ code with DRD (valgrind) finds a "Conflicting load", but I cannot see why. The code is as follows:

int* x;
int Nt = 2;

x = new int[Nt];

omp_set_num_threads(Nt);

#pragma omp parallel for
for (int i = 0; i < Nt; i++)
{
    x[i] = i;
}

for (int i = 0; i < Nt; i++)
{
    printf("%d\n", x[i]);
}

The program behaves well, but DRD sees an issue when the master thread prints out the value of x[1]. Apart from possible false sharing due to how the x array is allocated, I do not see why there should be any conflict, and how to avoid it... Any insights, please?

EDIT Here's the DRD output for the above code (line 47 corresponds to the printf statement):

==2369== Conflicting load by thread 1 at 0x06031034 size 4
==2369==    at 0x4008AB: main (test.c:47)
==2369== Address 0x6031034 is at offset 4 from 0x6031030. Allocation context:
==2369==    at 0x4C2DCC7: operator new[](unsigned long) (vg_replace_malloc.c:363)
==2369==    by 0x400843: main (test.c:37)
==2369== Other segment start (thread 2)
==2369==    at 0x4C31EB8: pthread_mutex_unlock (drd_pthread_intercepts.c:703)
==2369==    by 0x4C2F00E: vgDrd_thread_wrapper (drd_pthread_intercepts.c:236)
==2369==    by 0x5868D95: start_thread (in /lib64/libpthread-2.15.so)
==2369==    by 0x5B6950C: clone (in /lib64/libc-2.15.so)
==2369== Other segment end (thread 2)
==2369==    at 0x5446846: ??? (in /usr/lib64/gcc/x86_64-pc-linux-gnu/4.7.3/libgomp.so.1.0.0)
==2369==    by 0x54450DD: ??? (in /usr/lib64/gcc/x86_64-pc-linux-gnu/4.7.3/libgomp.so.1.0.0)
==2369==    by 0x4C2F014: vgDrd_thread_wrapper (drd_pthread_intercepts.c:355)
==2369==    by 0x5868D95: start_thread (in /lib64/libpthread-2.15.so)
==2369==    by 0x5B6950C: clone (in /lib64/libc-2.15.so)
È stato utile?

Soluzione

GNU OpenMP runtime (libgomp) implements OpenMP thread teams using a pool of threads. After they are created, the threads sit docked at a barrier where they wait to be awaken to perform a specific task. In GCC these tasks come in the form of outlined (the opposite of inlined) code segments, i.e. the code for the parallel region (or for the explicit OpenMP task) is extracted into a separate function and that is supplied to some of the waiting threads as a task for execution. The docking barrier is then lifted and the threads start executing the task. Once that is finished, the threads are docked again - they are not joined, but simply put on hold. Therefore from DRD's perspective the master thread, which executes the serial part of the code after the parallel region, is accessing without protection resources that might be written to by the other threads. This of course cannot happen since the other threads are docked and waiting for a new task.

Such false positives are common with general tools like DRD that do not understand the specific semantics of OpenMP. Those tools are thus not suitable for analysis of OpenMP programs. You should use instead a specialised tool, e.g. the free Thread Analyzer from Sun/Oracle Solaris Studio for Linux or the commercial Intel Inspector. The latter can be used for free with a license for non-commercial development purposes. Both tools understand the specifics of OpenMP and won't present such situations as possible data races.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top