Ефективно актуализирайте идентичен масив за всички задачи с 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)


Алгоритъмът, който описвате, е „всички към всички“. Всеки ранг актуализира част от по-голям масив и всички рангове трябва да синхронизират този масив от време на време.

Ако актуализациите се случват в контролирани точки в потока на програмата, моделът Gather/Scatter може да е от полза. Всички рангове изпращат своята актуализация до "ранг 0", а ранг 0 изпраща актуализирания масив на всички останали. В зависимост от размера на масива, броя на ранговете, връзката между всеки ранг и т.н.... този модел може да предложи по-малко режийни разходи от Allgatherv.

person Stan Graves    schedule 19.09.2011