Ваша программа не запускается параллельно, потому что параллельно запускать просто нечего. При первой записи в mario
, current_node
равно 9
, а vec
- это все 8
s, поэтому этот l oop в первой и единственной задаче никогда не выполняется:
for(int i = current_node;i <= vec[current_node];i++){
++steps;
mario(i + 1,new_depth);
}
Следовательно, нет рекурсивного создания новых задач. Как и что работает параллельно, когда вы компилируете его с помощью Clang, я не понимаю, поскольку, когда я компилирую его с помощью Clang 9, исполняемый файл ведет себя точно так же, как и тот, который создается G CC.
Второй код выполняется параллельно из-за рекурсивного вызова в l oop после области task
. Но это также неправильная программа OpenMP - спецификация запрещает вложение областей task
внутри конструкции simd
(см. В разделе Ограничения здесь ):
- Единственные конструкции OpenMP, которые можно встретить во время выполнения области
simd
, - это конструкция atomic
, конструкция loop
, конструкция simd
и конструкция ordered
с simd
clause.
Ни один из двух компиляторов не улавливает эту проблему, когда вложение находится в динамическом c, а не в лексической области конструкции simd
.
Редактировать: Я на самом деле внимательно посмотрел на него, и у меня может возникнуть подозрение, что могло вызвать ваше замешательство. Я думаю, вы определяете, работает ли ваша программа параллельно или нет, глядя на загрузку процессора во время ее работы. Это часто приводит к путанице. Среда выполнения Intel OpenMP, которую использует Clang, имеет очень агрессивную политику ожидания. Когда параллельная область в функции main()
порождает команду из четырех потоков, один из них выполняет mario()
, а три других сталкиваются с неявным барьером в конце области. Там они крутятся, ожидая, когда им в конце концов поставят новые задачи. Они никогда не получают ни одной, но все равно продолжают вращаться, и это то, что вы видите по загрузке процессора. Если вы хотите воспроизвести то же самое с G CC, установите OMP_WAIT_POLICY
на ACTIVE
, и вы увидите, что загрузка ЦП резко возрастает во время работы программы. Тем не менее, если вы профилируете выполнение программы, вы увидите, что время ЦП тратится внутри вашего кода только в одном потоке.