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