В начале #pragma omp parallel
создается цепочка потоков, затем, когда мы добираемся до #pragma omp for
, рабочая нагрузка распределяется. Что произойдет, если для цикла for внутри цикла есть цикл for, и я также разместил #pragma omp for
? Создает ли каждый поток новые потоки? Если нет, каким потокам назначена эта задача? Что именно происходит в этой ситуации?Что происходит в OpenMP, когда есть прагма для внутри прагмы?
ответ
По умолчанию нитки не создаются для внутреннего цикла. Он выполняется последовательно, используя поток, который достигает его.
Это связано с тем, что вложенность отключена по умолчанию. Однако, если вы включите вложенность через omp_set_nested()
, тогда будет создан новый набор потоков.
Однако, если вы не будете осторожны, то это приведет к p^2
количества нитей (так как каждый из исходных p
нитей будут появляться еще p
темы.) Поэтому вложенности отключена по умолчанию.
В такой ситуации, как следующее:
#pragma omp parallel
{
#pragma omp for
for(int ii = 0; ii < n; ii++) {
/* ... */
#pragma omp for
for(int jj = 0; jj < m; jj++) {
/* ... */
}
}
}
, что происходит в том, что вы вызвать неопределенное поведение, как вы нарушите стандарт OpenMP. Более точно вы нарушаете ограничения, возникающие в разделе 2.5 (распараллеливание конструкции):
Следующие ограничения распространяются на распараллеливание конструкций:
- Каждый распараллеливание регион должен столкнуться всеми потоками в команде или никем вообще.
- Последовательность областей регистрации и встречающихся областей барьеров должна быть одинаковой для каждого потока в команде.
Это четко показано в примерах A.39.1c and A.40.1c:
Пример A.39.1c: Следующий пример конструкция цикла вложенности в соответствии потому, что внутренние и внешние области петли связываются с различными параллельные регионы:
void work(int i, int j) {}
void good_nesting(int n)
{
int i, j;
#pragma omp parallel default(shared)
{
#pragma omp for
for (i=0; i<n; i++) {
#pragma omp parallel shared(i, n)
{
#pragma omp for
for (j=0; j < n; j++)
work(i, j);
}
}
}
}
Пример A.40.1c: Следующий пример несоответствующего, поскольку внутренние и внешние области петли тесно вложенный
void work(int i, int j) {}
void wrong1(int n)
{
#pragma omp parallel default(shared)
{
int i, j;
#pragma omp for
for (i=0; i<n; i++) {
/* incorrect nesting of loop regions */
#pragma omp for
for (j=0; j<n; j++)
work(i, j);
}
}
}
Обратите внимание, что это отличается от:
#pragma omp parallel for
for(int ii = 0; ii < n; ii++) {
/* ... */
#pragma omp parallel for
for(int jj = 0; jj < m; jj++) {
/* ... */
}
}
, в котором вы пытаетесь породить вложенный параллельная область. Только в этом случае обсуждается ответ «Мистический».
- 1. OpenMP: прагма отменить для ON NUMA
- 2. openMP условная прагма "if else"
- 3. Почему компилятор игнорирует прагмы OpenMP?
- 4. построить внутри прагмы для
- 5. Прагма SIMD от Intel против Прагма OMP SIMD OpenMP в
- 6. Что происходит, когда мы используем прагма-пакет (1)?
- 7. Что происходит, когда в FlatFileFooterCallback есть ошибка?
- 8. # прагма внутри #define
- 9. прагма OMP параллели против прагма OMP параллельно
- 10. Что происходит внутри, когда внешний поток закрыт?
- 11. Что именно происходит, когда есть исключение
- 12. Что происходит внутри, когда мы делаем downcasting?
- 13. Что происходит, когда есть несоответствие подписанного/неподписанного?
- 14. clang добавление новой прагмы
- 15. Что происходит внутри $ .each()?
- 16. латентность openmp для внутри для
- 17. Objective C закрывающая прагма-метка
- 18. Что происходит внутри моего окна?
- 19. Когда использовать прагмы на sqlite?
- 20. Что происходит, когда server.accept()
- 21. Что происходит, когда вызывается ShowMessage?
- 22. Что происходит с соединениями, когда есть больше, чем max_connections?
- 23. Что происходит внутри, когда вы вызываете функцию в php
- 24. Что происходит внутри моей петли?
- 25. Что происходит внутри диалогового конструктора
- 26. Что именно происходит внутри document.write()?
- 27. Что происходит, когда вызывается dbcontext.Database.ExecuteSqlCommand?
- 28. OpenMP: синхронизация внутри параллельно для
- 29. Что происходит, когда происходит тайм-аут WebClientProtocol
- 30. Что происходит, когда в java есть несколько основных методов?
Я думаю, что ваш ответ может быть неправильным в том смысле, что он обращается к другой ситуации от той, которую спрашивает ОП. – Massimiliano
@Massimiliano Hmm ... хорошо пункт. Но я не могу ни подтвердить, ни отрицать UB, что вы утверждаете в своем ответе, поскольку, похоже, у меня есть другая интерпретация этих двух пуль. – Mysticial
Какова ваша интерпретация? По крайней мере, согласны ли вы, что если 'n% nthreads!= 0', а расписание не является «статическим», тогда точка 2 всегда нарушается? – Massimiliano