Эффективно обновляйте идентичный массив для всех задач с помощью MPI

Я хотел бы повысить эффективность кода, который включает обновления каждого значения массива, который идентичен на всех процессорах, работающих с MPI. Основная структура, которую я сейчас имею, - это запоминать фрагменты данных в локальном массиве на каждом процессоре, работать с ними и Allgatherv (нужно использовать «v», потому что размер локальных блоков не является строго идентичным).

В C это будет выглядеть примерно так:

/* counts gives the parallelization, counts[RANK] is the local memory size */
/* offsets gives the index in the global array to the local processors */

memcpy (&local_memory[0], &total_vector[0], counts[RANK] * sizeof (double));
for (i = 0; i < counts[RANK]; i++)
  local_memory[i] = new_value;

MPI_Allgatherv (&local_memory[0], counts[RANK], MPI_DOUBLE, &total_vector[0], counts, offsets, MPI_DOUBLE, MPI_COMM_WORLD);

Как оказалось, это не очень эффективно. Фактически, это чертовски медленно, настолько плохо, что для большинства размеров систем, которые меня интересуют, распараллеливание не приводит к какому-либо увеличению скорости.

Я полагаю, что альтернативой этому было бы обновление только локальных фрагментов глобального вектора на каждом процессоре, а затем широковещательная передача правильного фрагмента памяти из правильной задачи всем другим задачам. Хотя это позволяет избежать явной обработки памяти, стоимость передачи широковещательной передачи должна быть довольно высокой. Фактически, это все для всех.

РЕДАКТИРОВАТЬ: Я просто пошел и попробовал это решение, в котором вам нужно перебрать количество задач и выполнить это количество операторов широковещательной передачи. Этот способ еще хуже.

У кого-нибудь есть лучшее решение?


c mpi
person coastal    schedule 15.09.2011    source источник
comment
Чтобы убедиться, что я правильно понимаю: каждый процессор должен обновить определенную часть вектора. И все процессоры должны в конечном итоге получать обновления от всех остальных процессоров? (поскольку они должны быть одинаковыми)   -  person Mysticial    schedule 16.09.2011
comment
Я как раз собирался опубликовать ответ о том, что может быть лучше или хуже, и вы сами ответили на него. У меня нет идей. Возможно, можно обойтись без пользовательских типов данных MPI, но я не слишком знаком с ними.   -  person Mysticial    schedule 16.09.2011
comment
Да, я действительно использую пользовательские типы данных в своих операторах MPI, я только что опубликовал простую версию идеи выше. Сборку можно было бы сделать быстрее, используя более крупные блоки, но я думаю, что в первую очередь проблема заключается в постоянной необходимости копировать глобальный вектор в локальную память на каждом процессоре. Это много работы. По сути, лучший вариант - просто распределить массив, но, к сожалению, остальная часть моего кода еще не поддерживает это, поэтому я ищу магию. Ха-ха.   -  person coastal    schedule 16.09.2011


Ответы (1)


Вы описываете алгоритм «все для всех». Каждый ранг обновляет часть большего массива, и все ранги должны время от времени синхронизировать этот массив.

Если обновления происходят в контролируемых точках потока программы, может быть полезен шаблон «Сбор / разброс». Все ранги отправляют свое обновление до «ранга 0», а ранг 0 отправляет обновленный массив всем остальным. В зависимости от размера массива, количества рангов, взаимосвязи между каждым рангом и т. Д. Этот шаблон может предложить меньше накладных расходов, чем Allgatherv.

person Stan Graves    schedule 19.09.2011