อันดับแรกคำตอบที่แน่นอนขึ้นอยู่กับ: (1) การใช้งานเช่นอาร์กิวเมนต์ของฟังก์ชันอินพุต (2) คุณภาพและรายละเอียดการใช้ MPI และ (3) ฮาร์ดแวร์ที่คุณใช้ บ่อยครั้งที่เกี่ยวข้องกับ (2) และ (3) เช่นเมื่อผู้จำหน่ายฮาร์ดแวร์ปรับ MPI ให้เหมาะสมสำหรับเครือข่าย
โดยทั่วไปแล้วการรวมกลุ่ม MPI จะดีกว่าสำหรับข้อความขนาดเล็กเนื่องจากค่าใช้จ่ายในการเริ่มต้นอาจไม่น่าสนใจและการซิงโครไนซ์ที่เกี่ยวข้องโดยการบล็อกกลุ่มควรจะลดลงหากมีการเปลี่ยนแปลงในเวลาคำนวณระหว่างการโทร สำหรับข้อความที่ใหญ่ขึ้นเป้าหมายควรจะลดจำนวนข้อมูลที่จะส่ง
ยกตัวอย่างเช่นในทางทฤษฎีMPI_Reduce_scatter_block
ควรจะดีกว่าMPI_Reduce
ตามมาด้วยMPI_Scatter
แม้ว่าในอดีตมักจะถูกนำไปใช้ในแง่ของสิ่งหลังซึ่งไม่มีประโยชน์จริง มีความสัมพันธ์กันระหว่างคุณภาพการปรับใช้และความถี่ในการใช้งานในการนำไปใช้งานส่วนใหญ่ของ MPI และผู้ขายเห็นได้ชัดว่าฟังก์ชั่นเหล่านั้นปรับฟังก์ชั่นการทำงานเหล่านี้ให้เหมาะสมกับสัญญาเครื่อง
ในทางตรงกันข้ามถ้ามีใครอยู่ในยีนสีน้ำเงินการMPI_Reduce_scatter_block
ใช้MPI_Allreduce
ซึ่งจะทำให้การสื่อสารมากกว่าMPI_Reduce
และMPI_Scatter
รวมกันเป็นจริงเร็วขึ้นเล็กน้อย นี่คือสิ่งที่ฉันค้นพบเมื่อเร็ว ๆ นี้และเป็นการละเมิดหลักการของความสอดคล้องในการปฏิบัติงานที่น่าสนใจใน MPI (หลักการนี้มีการอธิบายรายละเอียดเพิ่มเติมใน"แนวทางปฏิบัติงาน MPI ที่สอดคล้องกับตนเอง" )
ในกรณีเฉพาะของการกระเจิง + รวบรวมกับตัวรวบรวมพิจารณาว่าในอดีตข้อมูลทั้งหมดจะต้องไปและจากกระบวนการเดียวซึ่งทำให้เกิดคอขวดในขณะที่ในตัว allgather ข้อมูลสามารถไหลเข้าและออกจากตำแหน่งทั้งหมดได้ทันที เนื่องจากอันดับทั้งหมดมีข้อมูลที่จะส่งไปยังอันดับอื่นทั้งหมด อย่างไรก็ตามการส่งข้อมูลจากโหนดทั้งหมดในครั้งเดียวไม่จำเป็นต้องเป็นความคิดที่ดีในบางเครือข่าย
สุดท้ายวิธีที่ดีที่สุดในการตอบคำถามนี้คือทำสิ่งต่อไปนี้ในรหัสของคุณและตอบคำถามโดยการทดสอบ
#ifdef TWO_MPI_CALLS_ARE_BETTER_THAN_ONE
MPI_Scatter(..)
MPI_Gather(..)
#else
MPI_Allgather(..)
#endif
ตัวเลือกที่ดียิ่งขึ้นคือการให้โค้ดของคุณวัดค่าในระหว่างการทำซ้ำสองครั้งแรกจากนั้นใช้ค่าใดก็ตามที่เร็วกว่าสำหรับการวนซ้ำที่เหลืออยู่:
const int use_allgather = 1;
const int use_scatter_then_gather = 2;
int algorithm = 0;
double t0 = 0.0, t1 = 0.0, dt1 = 0.0, dt2 = 0.0;
while (..)
{
if ( (iteration==0 && algorithm==0) || algorithm==use_scatter_then_gather )
{
t0 = MPI_Wtime();
MPI_Scatter(..);
MPI_Gather(..);
t1 = MPI_Wtime();
dt1 = t1-t0;
}
else if ( (iteration==1 && algorithm==0) || algorithm==use_allgather)
{
t0 = MPI_Wtime();
MPI_Allgather(..);
t1 = MPI_Wtime();
dt2 = t1-t0;
}
if (iteration==1)
{
dt2<dt1 ? algorithm=use_allgather : algorithm=use_scatter_then_gather;
}
}
MPI_Scatter
ตามมาด้วยไม่ได้ให้การสื่อสารความหมายเดียวกันเป็นMPI_Gather
MPI_Allgather
บางทีอาจมีความซ้ำซ้อนเมื่อคุณแสดงการดำเนินการด้วยวิธีใด?