В чем разница между этими двумя?
[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
директивы fused вы можете делать обе вещи одновременно .
#pragma omp parallel for
директиву. Должна быть какая-то разница.
Вот пример использования разделенных parallel
и for
здесь . Вкратце, его можно использовать для динамического выделения частных массивов потоков OpenMP перед выполнением for
цикла в нескольких потоках. В parallel for
случае, если такую же инициализацию сделать невозможно .
UPD: В примере вопроса нет разницы между одной прагмой и двумя прагмами. Но на практике вы можете сделать более ориентированное на поток поведение с разделенными директивами parallel и for. Какой-то код, например:
#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 может генерировать немного другой код для этих двух случаев.
Я вижу совершенно разные времена выполнения, когда беру цикл for в 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 мс. код "parallel for" выполняется за 29 мс. Если я опущу for
и использую #pragma omp parallel
, время выполнения увеличится до 179 мс, что медленнее, чем последовательный код. (машина имеет параллелизм 8)
код ссылается на libgomp
#pragma omp for
вообще нет многопоточного разделения цикла. Но в любом случае это был не случай OP, попробуйте еще раз с дополнительным #pragma omp for
внутри, #pragm omp parallel
и он должен работать аналогично (если не так), как #pragma omp parallel for
версия.
Очевидно, существует множество ответов, но этот отвечает очень хорошо (с исходным кодом)
#pragma omp for
делегирует только части цикла для разных потоков в текущей команде. Команда - это группа потоков, выполняющих программу. При запуске программы команда состоит только из одного участника: главного потока, который запускает программу.Чтобы создать новую группу потоков, вам нужно указать ключевое слово parallel. Его можно указать в окружающем контексте:
#pragma omp parallel { #pragma omp for for(int n = 0; n < 10; ++n) printf(" %d", n); }
и:
Что такое: параллельно, для и команды
Разница между parallel, parallel for и for заключается в следующем:
Команда - это группа потоков, которые выполняются в данный момент. В начале программы команда состоит из одного потока. Параллельная конструкция разделяет текущий поток на новую группу потоков на время следующего блока / оператора, после чего группа снова объединяется в одну. for разделяет работу цикла for между потоками текущей команды.
Он не создает потоки, он только разделяет работу между потоками выполняющейся в данный момент команды. parallel for - это сокращение сразу для двух команд: parallel и for. Parallel создает новую команду, и при разделениях эта команда обрабатывает различные части цикла. Если ваша программа никогда не содержит параллельной конструкции, никогда не может быть более одного потока; главный поток, который запускает программу и запускает ее, как в непоточных программах.
schedule(static, chunk)
предложение в директиве, у меня возникает проблема. Код работает нормально, но когда я вызываю этот код из программы MPI, он заходит в бесконечный цикл. Счетчик цикла равен нулю на всех итерациях этого цикла. У меня счетчик циклов определен как частный в#pragma omp parallel
директиве. Понятия не имею, почему это не удается только тогда, когда MPI вызывает код. Я в некоторой степени уверен, что каждый процесс MPI выполняется на другом процессоре кластера, если это имеет значение. Понятия не имею, является ли расписание причиной проблемы.