İlk olarak, kesin cevap şöyledir: (1) kullanım, yani işlev giriş argümanları, (2) MPI uygulama kalitesi ve detayları ve (3) kullandığınız donanım. Genellikle, (2) ve (3), donanım satıcısının ağları için MPI'yi optimize etmesi gibi ilişkilidir.
Genel olarak, MPI kolektiflerinin kaynaştırılması daha küçük mesajlar için daha iyidir, çünkü başlangıç maliyetleri önemsiz olabilir ve aramalar arasında hesaplama süresinde değişiklik varsa kolektifleri engelleyerek yapılan senkronizasyon en aza indirilmelidir. Daha büyük mesajlar için amaç, gönderilen veri miktarını en aza indirmek olmalıdır.
Örneğin, teoride, birincisi genellikle ikincisi açısından uygulansa da, gerçek bir avantaj MPI_Reduce_scatter_block
olmayacak şekilde MPI_Reduce
takip edilenden daha iyi olmalıdır MPI_Scatter
. Çoğu MPI uygulamasında uygulama kalitesi ve kullanım sıklığı arasında bir korelasyon vardır ve satıcılar, bunun makine sözleşmesi için gerekli olduğu işlevleri açıkça optimize eder.
Öte yandan, bir Mavi Gen MPI_Reduce_scatter_block
üzerindeyse MPI_Allreduce
, daha fazla iletişim MPI_Reduce
ve MPI_Scatter
kombine olan kullanımı yapmak aslında biraz daha hızlıdır. Bu yakın zamanda keşfettiğim bir şey ve MPI'daki performans öz-tutarlılığı ilkesinin ilginç bir ihlalidir (bu ilke "Kendinden Tutarlı MPI Performans Kılavuzları" nda daha ayrıntılı olarak açıklanmaktadır ).
Saçılma + toplanmaya karşı belirli bir durumda, birincisinde, tüm verilerin tek bir sürece gidip gelmesi gerektiğini düşünün; , çünkü tüm sıralamaların diğer tüm sıralamalara gönderilecek bazı verileri vardır. Bununla birlikte, tüm düğümlerden bir kerede veri göndermek, bazı ağlar için iyi bir fikir olmayabilir.
Son olarak, bu soruya cevap vermenin en iyi yolu, kodunuzda aşağıdakileri yapmak ve soruyu denemeyle cevaplamaktır.
#ifdef TWO_MPI_CALLS_ARE_BETTER_THAN_ONE
MPI_Scatter(..)
MPI_Gather(..)
#else
MPI_Allgather(..)
#endif
Daha da iyi bir seçenek, kodunuzun ilk iki yineleme sırasında deneysel olarak ölçmesini sağlamak, ardından kalan yinelemeler için hangisinin daha hızlı olduğunu kullanmaktır:
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
izlediMPI_Gather
aynı iletişim anlamsal sağlamazMPI_Allgather
. Belki de işlemi her iki şekilde ifade ettiğinizde fazlalık söz konusudur?