2016-05-03 2 views
0

В моей основной функции я поставил:HTOP и OpenMP нитей

omp_set_num_threads(20); 

, который говорит OpenMP использовать 20 потоков (есть 40 темы, доступные).

я затем выполнить свой код, который содержит директиву:

#pragma omp parallel for shared(x,y,z) 

для основной цикл, и мониторинг использования процессора через Htop (возможно, не лучший способ, но все же). Есть 50 «задач», которые должен выполнить цикл for, и каждый из них занимает довольно много времени. То, что я наблюдаю через htop, заключается в том, что после завершения задач количество потоков падает. В частности, используя 20 потоков, я ожидаю, что ed увидит 2000% использования процессора, пока не останется меньше 20 задач, после чего потоки должны «освободиться». Однако то, что я вижу, - это первые 2000%, и после завершения n задач я вижу производительность 2000% - (n * 100%). Таким образом, кажется, что по мере завершения задач потоки закрываются, а не поднимают новые задачи.

Можно ли это ожидать или это звучит странно?

+0

Итак, после 20 задач загрузка процессора падает до нуля, а ваш параллельный цикл никогда не заканчивается? –

+0

Нет, он заканчивается. Мой вопрос в том, почему потоки, кажется, умирают, когда есть еще задачи, требующие обработки. – user1938803

+1

Поскольку 50 разделенных на 20 составляет 2,5, а планирование циклов по умолчанию с большинством компиляторов является «статическим», поэтому половина потоков обрабатывает две итерации, а другая половина - три итерации. –

ответ

1

Планирование параллельного цикла по умолчанию для практически всех существующих компиляторов OpenMP - это static, что означает, что среда выполнения OpenMP будет пытаться равномерно распределить пространство итераций между потоками и выполнить статическое задание. Поскольку у вас есть 50 итераций и 20 потоков, работа не может быть разделена поровну, так как 20 не делит 50. Поэтому половина потоков будет выполнять три итерации, а другая половина сделает две итерации.

В конце() конструкции есть неявный барьер, где завершающиеся потоки ждут завершения остальных потоков. В зависимости от реализации OpenMP барьер может быть реализован как занятый цикл ожидания, как операция ожидания для некоторого объекта синхронизации ОС или как комбинация обоих. В последних двух случаях использование процессора потоками, которые попадают в барьер, либо сразу упадет до нуля, когда они перейдут в прерывистый сон, либо изначально останется на 100% в течение короткого времени (цикл занятости), а затем опустится до нуля (ожидание).

Если итерации цикла занимают ровно столько же времени, тогда произойдет то, что изначальное использование ЦП будет на 2000%, а затем после двух итераций (и немного больше, если реализация барьера использует короткий цикл занятости) упадет до 1000%. Если итерации занимают разные промежутки времени каждый, то потоки будут поступать в разные моменты на барьер, а использование ЦП будет постепенно уменьшаться.

В любом случае используйте schedule(dynamic), чтобы каждая итерация передавалась первому потоку, чтобы стать доступной. Это улучшит использование ЦП в случае, когда итерации занимают различное время. Это не поможет, когда итерации принимают одинаковое количество времени каждый. Решение в последнем случае будет состоять в том, чтобы число итераций было целым числом, кратным количеству потоков.

Смежные вопросы