omp паралельна vs omp паралельна для


105

Яка різниця між цими двома?

[A]

#pragma omp parallel
{ 
    #pragma omp for
    for(int i = 1; i < 100; ++i)
    {
        ...
    }
}

[B]

#pragma omp parallel for
for(int i = 1; i < 100; ++i)
{
   ...
}

Відповіді:


65

Я не думаю, що різниці є, один - це ярлик для іншого. Хоча ваша точна реалізація може мати справу з ними по-різному.

Комбіновані паралельні конструкції обміну роботою - це ярлик для визначення паралельної конструкції, що містить одну конструкцію обміну роботою та ніяких інших операторів. Дозволені пункти - це об'єднання пропозицій, дозволених для паралельних і спільних робіт.

Взято з http://www.openmp.org/mp-documents/OpenMP3.0-SummarySpec.pdf

Характеристики для OpenMP є тут:

https://openmp.org/specifications/


66

Вони рівнозначні.

#pragma omp parallelпороджує групу ниток, при цьому #pragma omp forрозділяє ітерації циклів між породженими нитками. Ви можете зробити обидві речі одночасно за допомогою плавленої #pragma omp parallel forдирективи.


У своєму коді я використовую саме цю структуру. Однак, коли я використовую schedule(static, chunk)пункт для директиви, у мене виникає проблема. Код працює нормально, але коли я викликаю цей код у програмі MPI, він стикається з нескінченним циклом. Лічильник циклу дорівнює нулю у всіх ітераціях цього циклу. У #pragma omp parallelдирективі лічильник циклу визначений як приватний . Не маю уявлення, чому це не вдається лише тоді, коли MPI викликає код. Я дещо впевнений, що кожен процес MPI працює на іншому процесорі кластеру, якщо це має значення. Не маю уявлення, чи графік викликає проблему.
Рохіт Банга

Це ж добре працює, коли я використовую #pragma omp parallel forдирективу. Має бути якась різниця.
Рохіт Банга

1
Оновлення: Як виявляється, я спостерігаю за цією проблемою лише тоді, коли використовую пункт розкладу, тому я думаю, це не залежить від того, використовую я комбіновану паралель для двох чи двох директив.
Rohit Banga

28

Ось приклад використання розділених parallelі for тут . Коротше кажучи, його можна використовувати для динамічного розподілу OpenMP-потокових масивів OpenMP перед виконанням forциклу в декількох потоках. Неможливо зробити те саме ініціалізацію вparallel for випадку.

UPD: У прикладі запитання немає різниці між однією прагмою та двома прагмами. Але на практиці можна зробити більш обізнаною поведінку з розділеною паралеллю та для директив. Наприклад, якийсь код:

#pragma omp parallel
{ 
    double *data = (double*)malloc(...); // this data is thread private

    #pragma omp for
    for(1...100) // first parallelized cycle
    {
    }

    #pragma omp single 
    {} // make some single thread processing

    #pragma omp for // second parallelized cycle
    for(1...100)
    {
    }

    #pragma omp single 
    {} // make some single thread processing again

    free(data); // free thread private data
}

9

Хоча обидві версії конкретного прикладу є рівнозначними, як уже згадувалося в інших відповідях, між ними все ж є одна невелика різниця. Перша версія включає непотрібний неявний бар'єр, який зустрічається в кінці "omp for". Інший неявний бар'єр можна знайти в кінці паралельної області. Додавання "nowait" до "omp for" зробить два коди рівнозначними, принаймні з точки зору OpenMP. Я згадую про це, оскільки компілятор OpenMP міг генерувати трохи різний код для двох випадків.


7

Коли я беру цикл в g ++ 4.7.0 і використовую, я спостерігаю надзвичайно різні періоди виконання

std::vector<double> x;
std::vector<double> y;
std::vector<double> prod;

for (int i = 0; i < 5000000; i++)
{
   double r1 = ((double)rand() / double(RAND_MAX)) * 5;
   double r2 = ((double)rand() / double(RAND_MAX)) * 5;
   x.push_back(r1);
   y.push_back(r2);
}

int sz = x.size();

#pragma omp parallel for

for (int i = 0; i< sz; i++)
   prod[i] = x[i] * y[i];

серійний код (ні openmp) працює за 79 мс. код "паралель для" працює за 29 мс. Якщо я опущу forта використовую #pragma omp parallel, час виконання знімається до 179 мс, що повільніше, ніж серійний код. (машина має hw одночасність 8)

код посилається на libgomp


2
Я думаю, це тому, що omp паралельно виконує цикл в окремій потоці, не розділяючи його на нитки, тому головна нитка чекає завершення другої нитки. і час витрачає на синхронізацію.
Антиглук

7
Це тому, що без #pragma omp forцього взагалі немає багатопотокового спільного використання циклу. Але це все одно не було випадків з ОП, спробуйте ще раз з додатковим #pragma omp forусередині, #pragm omp parallelі він повинен працювати аналогічно (як не той самий), що і #pragma omp parallel forверсія.
Крістіан Рау

2
Я вважаю цю відповідь найкращою, оскільки вона показує, що вони не є "еквівалентом"
Failed Scientist

6

Відповідей очевидно багато, але цей відповідає на неї дуже гарно (з джерелом)

#pragma omp forлише делегує частини циклу для різних потоків у поточній команді. Команда - це група потоків, що виконують програму. При запуску програми команда складається лише з одного члена: головного потоку, який запускає програму.

Щоб створити нову команду ниток, потрібно вказати паралельне ключове слово. Його можна вказати в оточуючому контексті:

#pragma omp parallel
{
   #pragma omp for
   for(int n = 0; n < 10; ++n)
   printf(" %d", n);
}

і:

Що таке: паралельно, для та команда

Різниця між паралельними, паралельними для і для полягає в наступному:

Команда - це група потоків, які виконуються в даний час. На початку програми команда складається з однієї нитки. Паралельна конструкція розбиває поточну нитку на нову команду потоків протягом тривалості наступного блоку / оператора, після чого команда зливається назад в один. для розділення роботи for-циклу серед ниток поточної команди.

Він не створює потоки, він лише ділить роботу між потоками команди, що виконує в даний час. Паралельний параметр - це скорочення двох команд одночасно: паралельно і для. Паралельно створює нову команду і для розбиття цієї команди для обробки різних ділянок циклу. Якщо ваша програма ніколи не містить паралельну конструкцію, ніколи не буде більше ніж один потік; головний потік, який запускає програму та запускає її, як у програмах, що не мають нитки.

https://bisqwit.iki.fi/story/howto/openmp/

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.