[英]why is mpi_bcast so much slower than mpi_reduce?
使用MPI,我們可以進行廣播以將陣列發送到多個節點,也可以簡化將多個節點上的陣列組合到一個節點上。
我猜想,實現這些目標的最快方法將是使用二叉樹,其中每個節點要么發送到兩個節點(bcast),要么減少兩個節點(reduce),這將使節點數量成為時間的對數。
似乎沒有任何理由會比減少廣播特別慢?
我在4台計算機的群集上運行了以下測試程序,其中每台計算機具有12個內核。 奇怪的是,廣播比減少慢很多。 為什么? 有什么我可以做的嗎?
結果是:
inited mpi: 0.472943 seconds
N: 200000 1.52588MB
P = 48
did alloc: 0.000147641 seconds
bcast: 0.349956 seconds
reduce: 0.0478526 seconds
bcast: 0.369131 seconds
reduce: 0.0472673 seconds
bcast: 0.516606 seconds
reduce: 0.0448555 seconds
代碼是:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <ctime>
#include <sys/time.h>
using namespace std;
#include <mpi.h>
class NanoTimer {
public:
struct timespec start;
NanoTimer() {
clock_gettime(CLOCK_MONOTONIC, &start);
}
double elapsedSeconds() {
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
double time = (now.tv_sec - start.tv_sec) + (double) (now.tv_nsec - start.tv_nsec) * 1e-9;
start = now;
return time;
}
void toc(string label) {
double elapsed = elapsedSeconds();
cout << label << ": " << elapsed << " seconds" << endl;
}
};
int main( int argc, char *argv[] ) {
if( argc < 2 ) {
cout << "Usage: " << argv[0] << " [N]" << endl;
return -1;
}
int N = atoi( argv[1] );
NanoTimer timer;
MPI_Init( &argc, &argv );
int p, P;
MPI_Comm_rank( MPI_COMM_WORLD, &p );
MPI_Comm_size( MPI_COMM_WORLD, &P );
MPI_Barrier(MPI_COMM_WORLD);
if( p == 0 ) timer.toc("inited mpi");
if( p == 0 ) {
cout << "N: " << N << " " << (N*sizeof(double)/1024.0/1024) << "MB" << endl;
cout << "P = " << P << endl;
}
double *src = new double[N];
double *dst = new double[N];
MPI_Barrier(MPI_COMM_WORLD);
if( p == 0 ) timer.toc("did alloc");
for( int it = 0; it < 3; it++ ) {
MPI_Bcast( src, N, MPI_DOUBLE, 0, MPI_COMM_WORLD );
MPI_Barrier(MPI_COMM_WORLD);
if( p == 0 ) timer.toc("bcast");
MPI_Reduce( src, dst, N, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD );
MPI_Barrier(MPI_COMM_WORLD);
if( p == 0 ) timer.toc("reduce");
}
delete[] src;
MPI_Finalize();
return 0;
}
群集節點正在運行64位ubuntu 12.04。 我同時嘗試了openmpi和mpich2,並獲得了非常相似的結果。 該網絡不是千兆以太網,它不是最快的,但我最好奇的不是絕對速度,而是廣播和縮減之間的差距。
我認為這不能完全回答您的問題,但希望它能提供一些見識。
MPI只是一個標准。 它沒有定義每個函數的實現方式。 因此,MPI中某些任務的性能(在您的情況下為MPI_Bcast和MPI_Reduce)完全取決於您使用的實現。 您可能會使用點對點通信方法設計廣播,該方法的性能要比給定的MPI_Bcast好。
無論如何,您必須考慮這些功能的每個功能。 廣播是從一個過程中獲取信息,然后將其發送給所有其他過程。 reduce是從每個過程中獲取信息並將其簡化為一個過程。 根據(最新) 標准 ,MPI_Bcast被認為是一對一的集體操作,而MPI_Reduce被認為是一對一的集體操作。 因此,在兩種實現中都可能找到有關將二進制樹用於MPI_Reduce的直覺。 但是,它很可能在MPI_Bcast中找不到。 可能是這樣的情況,MPI_Bcast是使用非阻塞點對點通信(從包含信息的進程發送到所有其他進程)並在通信后全部等待來實現的。 無論如何,為了弄清楚這兩個函數是如何工作的,建議您深入研究您的OpenMPI和MPICH2實現的源代碼。
正如Hristo所說,這取決於緩沖區的大小。 如果要發送一個較大的緩沖區,廣播將不得不進行大量的大型發送,而接收操作會對緩沖區進行一些本地操作以將其減小為單個值,然后僅發送該值而不是整個緩沖區。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.