Снижение открытых MP сбивает с толку - PullRequest
2 голосов
/ 15 марта 2019

Итак, я пытался сделать простое умножение между двумя массивами, затем сложить результат каждого умножения, и я действительно смущен сокращением, вот мой код:

#include <omp.h>
#include <stdio.h>
#define SizeOfVector 8
#define NumberOfThreads 4
int main(){
    const int X[SizeOfVector] = {0,2,3,4,5,6,7,8};
    const int Y[SizeOfVector] = {1,2,4,8,16,32,64,128};
    int Result[SizeOfVector] = {0};
    int Sum = 0;
    unsigned short id;

    omp_set_num_threads(NumberOfThreads);

    #pragma omp parallel private(id)
    {
        id = omp_get_thread_num();

        #pragma omp for reduction(+:Sum)
        for(unsigned short i = 0; i < SizeOfVector; i++)
        {
            Result[i] = X[i] * Y[i];
            Sum = Result[i];    //Problem Here
            printf("Partial result by thread[%d]= %d\n", id, Result[i]);
        }
    }
    printf("Final result= %d\n", Sum);
    return 0;
}

Дело в том, что если я изменю «Sum = Result [i]» на «Sum + = Result [i]», я получу правильный результат. Почему это происходит? Разве локальная переменная Sum не создается и не инициализируется для каждого потока, тогда сокращение добавляет все это, когда все потоки завершены?

Вот результат с Sum + = Result [i]:

Partial result by thread[2]= 80
Partial result by thread[2]= 192
Partial result by thread[0]= 0
Partial result by thread[0]= 4
Partial result by thread[1]= 12
Partial result by thread[1]= 32
Partial result by thread[3]= 448
Partial result by thread[3]= 1024
Final result= 1792

И вот результат с Sum = Result [i]:

Partial result by thread[2]= 80
Partial result by thread[2]= 192
Partial result by thread[0]= 0
Partial result by thread[0]= 4
Partial result by thread[3]= 448
Partial result by thread[3]= 1024
Partial result by thread[1]= 12
Partial result by thread[1]= 32
Final result= 1252

1 Ответ

1 голос
/ 15 марта 2019

Каждый поток проходит две итерации, прежде чем прийти к окончательному результату для Sum. Поскольку вы не добавляете в Sum каждую итерацию, а назначаете ее, конечный результат будет просто Result[i] для того, что i было последним выполнением в этом потоке. Это значение, которое в итоге суммируется с результатами всех других потоков. Вам нужно Sum += Result[i], чтобы каждый поток продолжал работать Sum до тех пор, пока они не соберутся обратно и не добавят различные Sum.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...