Яка різниця між цими двома?
[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)
{
...
}
Яка різниця між цими двома?
[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)
{
...
}
Відповіді:
Я не думаю, що різниці є, один - це ярлик для іншого. Хоча ваша точна реалізація може мати справу з ними по-різному.
Комбіновані паралельні конструкції обміну роботою - це ярлик для визначення паралельної конструкції, що містить одну конструкцію обміну роботою та ніяких інших операторів. Дозволені пункти - це об'єднання пропозицій, дозволених для паралельних і спільних робіт.
Взято з http://www.openmp.org/mp-documents/OpenMP3.0-SummarySpec.pdf
Характеристики для OpenMP є тут:
Вони рівнозначні.
#pragma omp parallel
породжує групу ниток, при цьому #pragma omp for
розділяє ітерації циклів між породженими нитками. Ви можете зробити обидві речі одночасно за допомогою плавленої #pragma omp parallel for
директиви.
#pragma omp parallel for
директиву. Має бути якась різниця.
Ось приклад використання розділених 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
}
Хоча обидві версії конкретного прикладу є рівнозначними, як уже згадувалося в інших відповідях, між ними все ж є одна невелика різниця. Перша версія включає непотрібний неявний бар'єр, який зустрічається в кінці "omp for". Інший неявний бар'єр можна знайти в кінці паралельної області. Додавання "nowait" до "omp for" зробить два коди рівнозначними, принаймні з точки зору OpenMP. Я згадую про це, оскільки компілятор OpenMP міг генерувати трохи різний код для двох випадків.
Коли я беру цикл в 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
#pragma omp for
цього взагалі немає багатопотокового спільного використання циклу. Але це все одно не було випадків з ОП, спробуйте ще раз з додатковим #pragma omp for
усередині, #pragm omp parallel
і він повинен працювати аналогічно (як не той самий), що і #pragma omp parallel for
версія.
Відповідей очевидно багато, але цей відповідає на неї дуже гарно (з джерелом)
#pragma omp for
лише делегує частини циклу для різних потоків у поточній команді. Команда - це група потоків, що виконують програму. При запуску програми команда складається лише з одного члена: головного потоку, який запускає програму.Щоб створити нову команду ниток, потрібно вказати паралельне ключове слово. Його можна вказати в оточуючому контексті:
#pragma omp parallel { #pragma omp for for(int n = 0; n < 10; ++n) printf(" %d", n); }
і:
Що таке: паралельно, для та команда
Різниця між паралельними, паралельними для і для полягає в наступному:
Команда - це група потоків, які виконуються в даний час. На початку програми команда складається з однієї нитки. Паралельна конструкція розбиває поточну нитку на нову команду потоків протягом тривалості наступного блоку / оператора, після чого команда зливається назад в один. для розділення роботи for-циклу серед ниток поточної команди.
Він не створює потоки, він лише ділить роботу між потоками команди, що виконує в даний час. Паралельний параметр - це скорочення двох команд одночасно: паралельно і для. Паралельно створює нову команду і для розбиття цієї команди для обробки різних ділянок циклу. Якщо ваша програма ніколи не містить паралельну конструкцію, ніколи не буде більше ніж один потік; головний потік, який запускає програму та запускає її, як у програмах, що не мають нитки.
schedule(static, chunk)
пункт для директиви, у мене виникає проблема. Код працює нормально, але коли я викликаю цей код у програмі MPI, він стикається з нескінченним циклом. Лічильник циклу дорівнює нулю у всіх ітераціях цього циклу. У#pragma omp parallel
директиві лічильник циклу визначений як приватний . Не маю уявлення, чому це не вдається лише тоді, коли MPI викликає код. Я дещо впевнений, що кожен процес MPI працює на іншому процесорі кластеру, якщо це має значення. Не маю уявлення, чи графік викликає проблему.