OpenMP: параллельно для (i; ...) и значения i - PullRequest
0 голосов
/ 02 ноября 2011

У меня есть следующий параллельный фрагмент:

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

int main()
{

omp_set_num_threads(4);
    int i;
#pragma omp parallel private(i)
    {
#pragma omp for 
        for(i = 0;i < 10; i++) {
            printf("A  %d: %d\n", omp_get_thread_num(),i);
        }
#pragma omp critical
        printf("i  %d: %d\n", omp_get_thread_num(), i ); 
    }
}

Я думал, что после цикла у каждого потока будет i равное i последнему значению в цикле потока.Мой желаемый вывод будет:

A  0: 0
A  0: 1
A  0: 2
A  3: 9
A  2: 6
A  2: 7
A  2: 8
A  1: 3
A  1: 4
A  1: 5
i  0: 3
i  3: 10
i  2: 9
i  1: 6

, тогда как я получу:

A  0: 0
A  0: 1
A  0: 2
A  3: 9
A  2: 6
A  2: 7
A  2: 8
A  1: 3
A  1: 4
A  1: 5
i  0: -1217085452
i  3: -1217085452
i  2: -1217085452
i  1: -1217085452

Как заставить i хранить значение последней итерации?lastprivate(i) делает i = 10 для всех потоков, и это не то, что я хочу.

Ответы [ 2 ]

6 голосов
/ 02 ноября 2011

Оказывается, ты не можешь. OpenMP изменяет семантику программы.

Параллельные циклы for переписываются компилятором в соответствии с четко определенным набором правил.

Это также означает, что вы не можете прерваться, вернуться из такого цикла. Вы также не можете напрямую манипулировать переменной цикла. Условие цикла не может вызывать случайные функции или делать какие-либо условные выражения, короче говоря: a omp parallel for цикл равен не a для цикла

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

int main()
{

omp_set_num_threads(4);
#pragma omp parallel
    {
        int i;
#pragma omp for 
        for(i = 0;i < 10; i++) {
            printf("A  %d: %d\n", omp_get_thread_num(),i);
        }
#pragma omp critical
        printf("i  %d: %d\n", omp_get_thread_num(), i ); 
    }
}
1 голос
/ 02 ноября 2011

Благодаря посту sehe, я выяснил следующий подвох, который решает проблему

    int i, last_i;
#pragma omp parallel private(i)
    {
#pragma omp for 
        for(i = 0;i < 10; i++) {
            printf("A  %d: %d\n", omp_get_thread_num(),i);
            last_i = i;
        }
#pragma omp critical
        printf("i  %d: %d\n", omp_get_thread_num(), last_i ); 
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...