Теория и практика параллельных вычислений

         

Балансировка вычислительной нагрузки процессоров


Как уже отмечалось ранее, вычислительная нагрузка при волновой обработке данных изменяется динамически в ходе вычислений. Данный момент следует учитывать при распределении вычислительной нагрузки между процессорами. Так, например, при фронте волны из 5 блоков и при использовании 4 процессоров обработка волны потребует двух параллельных итераций, во время второй из которых будет задействован только один процессор, а все остальные процессоры будут простаивать, дожидаясь завершения вычислений. Достигнутое ускорение расчетов в этом случае окажется равным 2,5 вместо потенциально возможного значения 4. Подобное снижение эффективности использования процессоров становится менее заметным при большой длине волны, размер которой может регулироваться размером блока. Как общий результат, можно отметить, что размер блока определяет степень разбиения (granularity) вычислений для распараллеливания и является параметром, подбирая значения которого можно управлять эффективностью параллельных вычислений.

Для обеспечения равномерности (балансировки) загрузки процессоров можно задействовать еще один подход, широко используемый для организации параллельных вычислений. Этот подход состоит в том, что все готовые к выполнению в системе вычислительные действия организуются в виде очереди заданий. В ходе вычислений освободившийся процессор может запросить для себя работу из этой очереди; появляющиеся по мере обработки данных новые вычислительные задания пополняют очередь заданий. Такая схема балансировки вычислительной нагрузки между процессорами является простой, наглядной и эффективной. Это позволяет говорить об использовании очереди заданий как общей модели организации параллельных вычислений для систем с общей памятью.

Указанная схема балансировки может быть применена и для рассматриваемого примера. В самом деле, в ходе обработки фронта текущей волны происходит постепенное формирование блоков следующей волны вычислений. Эти блоки могут быть задействованы для обработки при нехватке достаточной вычислительной нагрузки для процессоров.


Общая схема вычислений с использованием очереди заданий может быть представлена в следующем виде:

Алгоритм 11.7. Общая схема вычислений с использованием очереди

// Алгоритм 11.7 // <инициализация служебных данных> // <загрузка в очередь указателя на начальный блок> // взять блок из очереди (если очередь не пуста) while ( (pBlock=GetBlock()) != NULL ) { // <обработка блока> // отметка готовности соседних блоков omp_set_lock(pBlock->pNext.Lock); // сосед справа pBlock->pNext.Count++; if ( pBlock->pNext.Count == 2 ) PutBlock(pBlock->pNext); omp_unset_lock(pBlock->pNext.Lock); omp_set_lock(pBlock->pDown.Lock); // сосед снизу pBlock->pDown.Count++; if ( pBlock->pDown.Count == 2 ) PutBlock(pBlock->pDown); omp_unset_lock(pBlock->pDown.Lock); } // завершение вычислений, т.к. очередь пуста

Для описания имеющихся в задаче блоков узлов сетки в алгоритме используется структура со следующим набором параметров:

  • Lock – семафор, синхронизирующий доступ к описанию блока;
  • pNext – указатель на соседний справа блок;
  • pDown – указатель на соседний снизу блок;
  • Count – счетчик готовности блока к вычислениям (количество готовых границ блока).


Операции для выборки из очереди и вставки в очередь указателя на готовый к обработке блок узлов сетки обеспечивают соответственно функции GetBlock и PutBlock.

Как следует из приведенной схемы, процессор извлекает блок для обработки из очереди, выполняет необходимые вычисления для блока и отмечает готовность своих границ для соседних справа и снизу блоков. Если при этом оказывается, что у соседних блоков являются подготовленными обе границы, процессор передает эти блоки для запоминания в очередь заданий.

Использование очереди заданий позволяет решить практически все оставшиеся вопросы организации параллельных вычислений для систем с общей памятью. Развитие рассмотренного подхода может предусматривать уточнение правил выделения заданий из очереди для согласования с состояниями процессоров (близкие блоки целесообразно обрабатывать на одних и тех же процессорах), расширение числа имеющихся очередей заданий и т.п.Дополнительная информация по этим вопросам может быть получена, например, в [[63], [76]].


Содержание раздела