В данный момент я готовлюсь к экзамену, и один из практических вопросов - написать фрагмент кода, который реализует параллельную сумму всех элементов массива на компьютере SMP. Раньше я написал несколько программ OpenMP, которые были очень большими, но на самом деле не пользовались преимуществами предложений и директив, и я натолкнулся на предложение сокращения, поэтому мне было интересно, является ли следующий фрагмент параллельной программой, потому что мне интересно, как относительно упрощенно, можно ли сократить программу до параллелизма, но все же сохранить?

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


int main(int argc, char ** argv){

    int n = atoi(argv[1]);
    double * X;
    X = malloc(n * sizeof(double));
    for(int i = 0; i < n; i++){ X[i] = 2.0; }

    int i = 0;
    double sum = 0.0;

    omp_set_num_threads(atoi(argv[2]));

    #pragma omp parallel for private(i), shared(X) reduction(+: sum)
    for(i = 0; i < n; i++){

        sum += X[i];

    }

    printf("Sum is : %0.2f\n", sum);

    return 0;
}

0
Mr.Bloom 5 Дек 2020 в 21:27

2 ответа

Лучший ответ

Почему бы просто не запустить и не протестировать. Вы также можете запустить что-то подобное на своем ноутбуке / настольном компьютере. Да, операция редукции в этом коде параллельна (вычисление суммы). Однако установка элементов массива X на 2.0 выполняется последовательно. Вам нужно #pragma omp parallel for над for(int i = 0; i < n; i++){ X[i] = 2.0; }, чтобы сделать программу действительно параллельной. В противном случае будет применяться закон Амдала.

1
Kartik Lakhotia 5 Дек 2020 в 18:38

Я наткнулся на предложение сокращения, поэтому мне было интересно, является ли следующий фрагмент параллельной программой

Из стандарта OpenMP на #pragma omp parallel:

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

Так что да, это параллельная программа до тех пор, пока количество потоков, которые вы явно указали в методе:

omp_set_num_threads(atoi(argv[2]));

Больше 1.

У вас там небольшая опечатка:

#pragma omp parallel for private(i), shared(X) reduction(+: sum)

Должно быть:

#pragma omp parallel for private(i) shared(X) reduction(+: sum)

На самом деле частный i можно опустить, потому что, поскольку он используется как index в параллельном цикле, OpenMP сделает его частным.

0
dreamcrash 5 Дек 2020 в 19:43