Does the compiler detect a false shared variable?

Since I prepared a sample code for a small OpenMP presentation to my teammate, I found a strange case. First I wrote a classic loop:

void sequential(int *a, int size, int *b) { int i; for (i = 0; i < size; i++) { b[i] = a[i] * i; } } 

Proper use of OpenMP for the for directive is simple. We just need to move the int i declaration to scope to make it private .

 void parallel_for(int *a, int size, int *b) { #pragma omp parallel for for (int i = 0; i < size; i++) { b[i] = a[i] * i; } } 

But when I wrote the following function, I expected that I would get a different result from 2 others due to the common int j declared outside the range of the for loop. But, using my test structure, I do not see the expected error, the wrong value at the output of this function.

 void parallel_for_with_an_usage_error(int *a, int size, int *b) { int j; #pragma omp parallel for for (int i = 0; i < size; i++) { /*int*/ j = a[i]; //To be correct j should be declared here, in-loop to be private ! j *= i; b[i] = j; } } 

I have the full source code for testing, it builds with VS'12 and gcc (with C ++ 11 support) here http://pastebin.com/NJ4L0cbV

Do you have any idea what the compiler is doing? Does it detect false sharing, does this move int j in the loop due to optimization heuristics?

thanks

+4
source share
1 answer

In my opinion, what can happen is that the compiler does some optimization. Since in the above inserted code (without cout) the variable j is nowhere else than inside the loop, the compiler can put the declaration j inside the loop in the resulting assembly code.

Another possibility is that the compiler can convert three statements inside a loop into one statement, i.e. of

 /*int*/ j = a[i]; //To be correct j should be declared here, in-loop to be private ! j *= i; b[i] = j; 

in

 b[i] = a[i] * i; 

The compiler will perform this optimization regardless of whether its code is OpenMP or not.

0
source

Source: https://habr.com/ru/post/1495021/


All Articles