Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenMP odd behaviour with SIMD linear and parallel for linear directives

Tags:

c++

simd

openmp

I am learning how to use OpenMP with C++ using GNU C compiler 6.2.1 and I tested the following code:

#include <stdio.h>
#include <omp.h>
#include <iostream>

int b=10;

int main()
{
    int array[8];
    std::cout << "Test with #pragma omp simd linear:\n";
    #pragma omp simd linear(b)
    for (int n=0;n<8;++n) array[n]=b;

    for (int n=0;n<8;++n) printf("Iteration %d: %d\n", n, array[n]);

    std::cout << "Test with #pragma omp parallel for linear:\n";
    #pragma omp parallel for linear(b)
    for (int n=0;n<8;++n) array[n]=b;

    for (int n=0;n<8;++n) printf("Iteration %d: %d\n", n, array[n]);
}

In both cases I expected a list of numbers going from 10 to 17, however, this was not the case. The #pragma omp simd linear(b) is outright ignored, printing only 10 for each value in array. For #pragma omp parallel for linear(b) the program outputs 10,10,12,12,14,14,16,16.

I compile the file using g++ -fopenmp -Wall main.cpp -o main.o. How can I fix this?

EDIT: Reading the specification more carefully I found that the linear clausule overwrites the initial value with the last value obtained (i.e. if we start with b=10 after the first cycle we have b=17). However, the program runs correctly if I add schedule(dynamic) to the parallel for cycles. Why would I have to specify that parameter in order to have a correct execution?

like image 928
Sandthief Avatar asked Oct 31 '25 12:10

Sandthief


1 Answers

The OpenMP specification says:

The linear clause declares one or more list items to be private and to have a linear relationship with respect to the iteration space of a loop associated with the construct on which the clause appears.

This is an information only to the compiler to indicate the linear behavior of a variable in a loop, but in your code b is not increased at all. That is the reason you always get 10 in the first loop. So, the strange results obtained is not the compiler's fault. To correct it you have to use array[n]=b++;

On the other hand, for #pragma omp parallel for linear(b) loop, OpenMP calculates the starting b value for each thread (based on the linear relationship), but this value is still not increased in a given thread. So, depending on the number of threads used you will see different number of "steps".

In the case of schedule(dynamic) clause, the chunk_size is 1, so each loop cycle runs in a different thread. In this case the initial b value is always calculated by OpenMP, so you get correct values only.

like image 155
Laci Avatar answered Nov 03 '25 05:11

Laci