我有一个我需要时间的MPI代码(由其他人编写)。代码的基本布局如下。简而言之,代码在两部分中对矩阵A
进行并行SVD求解:(1)首先在A
处理器之间均匀地分割矩阵n
,然后(2)执行SVD求解:
int main(){
1. Code to split A among the different processors...
2. actual parallel SVD solve
}
我想只计算代码的第(2)部分(A在处理器之间分配后的SVD求解)。我尝试了以下内容,但我不确定输出是否正确:
int main(){
1. Code to split A among the different processors...
MPI_Barrier(MPI_COMM_WORLD);
double start = MPI_Wtime();
2. actual parallel SVD solve
MPI_Barrier(MPI_COMM_WORLD);
double end = MPI_Wtime();
if (MyPID == 0){ cout << end - start << endl;}
}
我对MPI很新,不确定我是否正确使用MPI_Barrier命令,或者我是否真的需要它。输出时间是否会正确地忽略第(1)部分所需的时间?
答案 0 :(得分:2)
如果我理解正确,您只想做分布式SVD。你看过线性代数库ScaLAPACK了吗?凭借其commands for singular value decomposition,它应该完全符合您的需要。
关于你对MPI_Barrier
的使用:它并不多:传递的通信器上的所有进程都等到该通信器上的每个其他进程都到达这行代码。但是MPI_Barrier
并不能保证在屏障同步后执行。首先,即使由于中断而在相同的CPU类型上执行,每个进程的性能也会略有不同;其次,在MPI_Barrier
之后执行恢复时,时间上存在微小的差异。总的来说,你应该尽可能避免MPI_Barrier
。我认为它更像是一种调试工具,而不是人们希望在生产代码中看到的东西。另外:当您计划使用集体沟通时,您不需要MPI_Barrier
。
总体设计的最后一句话:MPI中的初学者通常会犯错,他们认为有一个主进程管理所有信息并将问题分发给工作节点是有用的。但是,这种设计确实意味着很多通信和同步。通信(尤其是计算机之间的通信)相对较慢,应不惜一切代价避免。更有益的方法通常是 flat 设计,其中每个流程都会根据自身的一部分进行咀嚼。
编辑刚刚看到关于MPI_Wtime
的行:该代码段似乎是正确的。再举一个例子,你可以看看this tutorial。如果这个程序的唯一目的是测量时间,我想第一个MPI_Barrier
有点可行,但第二个当然不是。为什么在停止计时之前必须同步你的流程? MPI_Wtime
是正在执行它的进程的本地。
还有一件事:如果您有权访问VampirTrace(请询问您的群集管理员),您可以进行更深入的分析并获得漂亮的图表:
p.s。:任何人都可以推荐VampirTrace的免费变体吗?