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