进程数量增加导致MPI性能损失 我使用C++与MPI执行一些线性代数计算,如特征值分解。这些计算对于每个进程来说都是完全局部的,因此我认为只要有足够的计算资源,单个进程的性能就不应该受到我运行的进程总数的影响

进程数量增加导致MPI性能损失 我使用C++与MPI执行一些线性代数计算,如特征值分解。这些计算对于每个进程来说都是完全局部的,因此我认为只要有足够的计算资源,单个进程的性能就不应该受到我运行的进程总数的影响,c++,performance,mpi,armadillo,intel-mkl,C++,Performance,Mpi,Armadillo,Intel Mkl,然而,事实证明,随着进程总数的增加,每个进程的性能都会降低。在由2个Intel Xeon Gold 6132 CPU(总共28个物理内核,或56个线程)组成的节点上,我的测试发现,2000 x 2000对称矩阵的特征分解对于单个进程大约需要1.1秒,对于4个独立进程(使用mpirun-np 4./test)需要1.3秒,对于12个进程需要1.8秒 我想知道,这是MPI的预期行为,还是我错过了一些绑定选项?我尝试过“mpirun-np12——绑定到core:12./test”,但没有任何帮助。我正

然而,事实证明,随着进程总数的增加,每个进程的性能都会降低。在由2个Intel Xeon Gold 6132 CPU(总共28个物理内核,或56个线程)组成的节点上,我的测试发现,2000 x 2000对称矩阵的特征分解对于单个进程大约需要1.1秒,对于4个独立进程(使用mpirun-np 4./test)需要1.3秒,对于12个进程需要1.8秒

我想知道,这是MPI的预期行为,还是我错过了一些绑定选项?我尝试过“mpirun-np12——绑定到core:12./test”,但没有任何帮助。我正在使用犰狳库,它与Intel MKL链接。环境变量MKL_NUM_THREADS设置为1。源代码附在后面

#include <mpi.h>
#include <armadillo>
#include <chrono>
#include <sstream>

using namespace arma;
using iclock = std::chrono::high_resolution_clock;

int main(int, char**argv) {

    ////////////////////////////////////////////////////
    //              MPI Initialization
    ////////////////////////////////////////////////////
    int id, nprocs;
    MPI_Init(nullptr, nullptr);
    MPI_Comm_rank(MPI_COMM_WORLD, &id);
    MPI_Comm_size(MPI_COMM_WORLD, &nprocs);

    ////////////////////////////////////////////////////
    //              parse arguments
    ////////////////////////////////////////////////////
    int sz = 0, nt = 0;
    std::stringstream ss; 

    if (id == 0) {
        ss << argv[1];
        ss >> sz; 
        ss.clear();
        ss.str("");

        ss << argv[2];
        ss >> nt; 
        ss.clear();
        ss.str("");
    }   

    MPI_Bcast(&sz, 1, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(&nt, 1, MPI_INT, 0, MPI_COMM_WORLD);

    ////////////////////////////////////////////////////
    //                test and timing
    ////////////////////////////////////////////////////
    mat a = randu(sz, sz);
    a += a.t();

    mat evec(sz, sz);
    vec eval(sz);

    iclock::time_point start = iclock::now();

    for (int i = 0; i != nt; ++i) {
        //evec = a*a;
        eig_sym(eval, evec, a); // <-------here
    }   

    std::chrono::duration<double> dur = iclock::now() - start;

    double t = dur.count() / nt;

    ////////////////////////////////////////////////////
    //               collect timing
    ////////////////////////////////////////////////////
    vec durs(nprocs);
    MPI_Gather(&t, 1, MPI_DOUBLE, durs.memptr(), 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);

    if (id == 0) {
        std::cout << "average time elapsed of each proc:" << std::endl;
        durs.print();
    }

    MPI_Finalize();

    return 0;
}

#包括
#包括
#包括
#包括
使用arma;
使用iclock=std::chrono::高分辨率时钟;
int main(int,字符**argv){
////////////////////////////////////////////////////
//MPI初始化
////////////////////////////////////////////////////
int id,NPROC;
MPI_Init(nullptr,nullptr);
MPI通信等级(MPI通信世界和id);
MPI通信大小(MPI通信世界和NPROC);
////////////////////////////////////////////////////
//解析参数
////////////////////////////////////////////////////
int sz=0,nt=0;
std::stringstream-ss;
如果(id==0){
ss>sz;
ss.clear();
ss.str(“”);
ss>nt;
ss.clear();
ss.str(“”);
}   
MPI_Bcast(和sz,1,MPI_INT,0,MPI_COMM_WORLD);
MPI_Bcast(&nt,1,MPI_INT,0,MPI_COMM_WORLD);
////////////////////////////////////////////////////
//测试和计时
////////////////////////////////////////////////////
mat a=randu(sz,sz);
a+=a.t();
mat evec(深圳、深圳);
vec-eval(sz);
iclock::time_point start=iclock::now();
对于(int i=0;i!=nt;++i){
//evec=a*a;

环境影响评估(评估、评估、评估);//您是将总运行时间除以进程数,还是考虑调度开销?运行时的工作调度器将需要一些开销处理时间,这些开销处理时间将随着进程数与机器上核心数的比率而增加。您可能需要降低并行度粒度(每个处理器的进程数)以优化速度。这是正常情况下的预期行为

但是,您设置的条件不正常。 设置
MKL\u NUM\u THREADS=1
可防止产生超过1个线程!
删除设置
MLK_NUM_THREADS
的行,系统将为您处理该行。

您是将总运行时间除以进程数,还是考虑调度开销?运行时的工作调度程序将需要一些开销处理时间,这些开销处理时间随着进程数的比率而增加ses取决于计算机上的内核数。您可能需要降低并行粒度(每个处理器的进程数)以优化速度。这是正常情况下的预期行为

但是,您设置的条件不正常。 设置
MKL\u NUM\u THREADS=1
可防止产生超过1个线程!
删除设置
MLK_NUM_THREADS
的行,系统将为您处理它。

这是一种预期行为。要获得MPI的性能,您必须执行数据分解(负载平衡)、通信优化(阻塞与非阻塞)等

正如我从问题中了解到的,12个进程正在对12个
2000X2000
矩阵进行计算,平均时间为1.8秒,而执行计算的单个进程平均只需要1.2秒

是的,对于上述场景,MPI性能不会比单个流程更好,并且必须更高,原因如下(其中一些由Hristo Iliev在评论中提到):

  • MPI引起的开销
  • MPI中最慢进程所用的时间
  • 内存带宽(每个进程需要访问2000*2000矩阵,可能导致争用)
  • 缓存(处理器之间共享更高级别的缓存,多个进程等频繁访问缓存可能会影响整体应用程序性能)
  • 此外,性能改进(加速)将基于应用程序的并行部分,因为应用程序中没有并行部分,所以您不会看到并行化的任何好处


    此外,如果一个2000X2000矩阵分布在12个进程中,我们无法保证MPI的性能优于单个进程。它将取决于实现。这是一种预期行为。要获得MPI的性能,您必须执行数据分解(负载平衡)、通信优化(阻塞与非阻塞)等等

    正如我从问题中了解到的,12个进程正在对12个
    2000X2000
    矩阵进行计算,平均时间为1.8秒,而执行计算的单个进程平均只需要1.2秒

    是的,对于上述场景,MPI性能不会比单个流程更好,并且必须更高,原因如下(其中一些由Hristo Iliev在评论中提到):

  • MPI引起的开销
  • MPI中最慢进程所用的时间
  • 内存带宽(每个进程需要