Я хотел бы повысить эффективность кода, который включает обновления каждого значения массива, который идентичен на всех процессорах, работающих с 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);
Как оказалось, это не очень эффективно. Фактически, это чертовски медленно, настолько плохо, что для большинства размеров систем, которые меня интересуют, распараллеливание не приводит к какому-либо увеличению скорости.
Я полагаю, что альтернативой этому было бы обновление только локальных фрагментов глобального вектора на каждом процессоре, а затем широковещательная передача правильного фрагмента памяти из правильной задачи всем другим задачам. Хотя это позволяет избежать явной обработки памяти, стоимость передачи широковещательной передачи должна быть довольно высокой. Фактически, это все для всех.
РЕДАКТИРОВАТЬ: Я просто пошел и попробовал это решение, в котором вам нужно перебрать количество задач и выполнить это количество операторов широковещательной передачи. Этот способ еще хуже.
У кого-нибудь есть лучшее решение?