OpenMP разделы и одиночные - PullRequest
1 голос
/ 18 января 2020

Привет :) У меня проблема с этим кодом. В Linux работает нормально, но в Visual Studio:

переменные a, b, c используются без инициализации.

//#include "pch.h"
#include <omp.h>
#include <iostream>
using namespace std;

int fun1(int a) { return a * a; };
int fun2(int a) { return a + a; };
int fun3(int a) { return a + a + a; };
void printFun(int a, int b, int c) { cout << "\na: " << a << " b: " << b << " c: " << c; };

int main()
{
    omp_set_num_threads(4);

#pragma omp parallel
    {
        int a, b, c;
        #pragma omp sections
        {
            #pragma omp section
            a = fun1(3);
            #pragma omp section
            b = fun2(2);
            #pragma omp section
            c = fun3(4);
        }

        #pragma omp single //master
        printFun(a, b, c);
    }
}

Когда я меняю 'single' на ' master, все работает, но я не понимаю, почему я не могу использовать «single», например, когда я использую «for» вместо «section».

Спасибо за вашу помощь

sfmbe

1 Ответ

2 голосов
/ 18 января 2020

Я думаю, что код не должен работать вообще, компилятор MSV C на самом деле делает "правильные вещи".

Проблема в том, что код объявляет a, b, c как поток -приватные переменные. Когда каждый из потоков выполняет один раздел конструкции sections, он инициализирует свою собственную переменную:

поток 0: инициализированный, b & c не инициализированный поток 1: а не инициализированный, b инициализированный, c не инициализированный поток 2: a & b не инициализирован, c инициализирован

Когда код достигает конструкции single, для выполнения конструкции выбирается произвольный поток, поэтому в зависимости от того, какой из выбрано четыре потока, вы увидите другой результат.

Этот код будет работать так, как вы ожидаете, так как теперь a, b, c являются общими переменными, и, таким образом, все потоки видят инициализированную переменную:

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

using namespace std;

int fun1(int a) { return a * a; };
int fun2(int a) { return a + a; };
int fun3(int a) { return a + a + a; };
void printFun(int a, int b, int c) { cout << "\na: " << a << " b: " << b << " c: " << c; };

int main() {
    omp_set_num_threads(4);
    int a, b, c;
#pragma omp parallel
    {
        #pragma omp sections
        {
            #pragma omp section
            a = fun1(3);
            #pragma omp section
            b = fun2(2);
            #pragma omp section
            c = fun3(4);
        }

        #pragma omp single
        printFun(a, b, c);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...