c++ - MPI_Win_create 在原点的运行时间随着目标窗口大小的增加而增加
问题描述
我刚刚开始研究 MPI,并且正在做一个实验,我正在测量 MPI_Win_create 的运行时间。我正在使用mpich 3.4.1
图书馆。在这个实验中,我有两个进程 --- origin 和 target。我有以下代码行来测量运行时间:
double startTime, endTime;
startTime = MPI_Wtime();
MPI_Win_create(buffer, bufferSize, sizeof(char), MPI_INFO_NULL, MPI_COMM_WORLD, win);
endTime = MPI_Wtime();
double winCreateTime = endTime - startTime;
在我的实验中,原始进程(rank==0)的 bufferSize 始终为零。但是,在目标进程(rank==1)中,我将缓冲区大小增加到大约 2GB。我在源进程和目标进程的运行时 MPI_Win_create 中看到以下趋势:
MPI_Win_create time = 2.21
目标进程、源进程和目标进程的缓冲区大小约为 100MB 0.001071
。MPI_Win_create time = 25.21
目标进程、源进程和目标进程的缓冲区大小约为 1GB 0.000894
。在 2GB 左右,我在 origin processMPI_Win_create time = 41.580131
和 target process 看到了MPI_Win_create time = 0.000999
。对于我尝试过的各种数据大小,这种趋势是相同的。也就是说,原始进程的 MPI_Win_create 时间始终高于目标进程(并且随着数据大小的增加而增加)。在目标过程中,它要低得多。
据我了解,在调用 MPI_Win_create 时,相应的进程会创建一个 RMA 窗口,该窗口在相应进程的地址空间中公开内存区域,从指向的位置开始,buffer
该区域的大小为bufferSize
。我无法理解为什么当目标进程的 bufferSize 增加时,MPI_Win_create 的运行时间会在源进程中增加。以及为什么在目标进程端 MPI_Win_create 的运行时间或多或少是恒定的并且即使随着bufferSize
. 源端发生了什么而目标端没有发生?
解决方案
回答我自己的问题。在深入挖掘之后,我发现源进程和目标进程之间运行时不平衡的原因是由于在测量开始时间之前缺乏同步。
MPI_Win_create 是一个集合函数调用,其中通信器中的所有进程进行通信并创建一个 MPI 窗口。因此,到达此函数调用的任何进程似乎都被阻止,其他参与进程也无法在其各自的代码中到达这一点。就我而言,目标进程在调用 MPI_Win_create 之前正在生成大量数据。然而,在这一点之前,起源做的工作很少。因此,对于起点,点的startTime
到达时间比目标点要早得多。因此,my endTime - startTime
at origin process 也包含了 target process 的数据生成时间,因为它需要等待 target process 完成数据生成并到达其对应的 MPI_Win_create。然而,在目标方面,endTime - startTime
是目标在其 MPI_Win_create 上花费的实际时间。
解决方案:我能够在测量 startTime 之前使用 MPI_Barrier() 获得合理的运行时间,如以下模型代码片段所示。通过此更改,对于大约 2GB 的缓冲区大小,我在大约 0.000347 秒的原始进程和大约 0.000382 秒的目标进程处获得 MPI_Win_create 运行时。
#include <mpi.h>
#define ORIGIN 0
#define TARGET 1
int main(int argc, char *argv[]) {
MPI_Init(&argc, &argv);
int my_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
double startTime, endTime;
char *buffer = nullptr;
long bufferSize = 0;
if (my_rank == TARGET) {
bufferSize = 2000000000;
buffer = new char[bufferSize](); //OR, getLargeData()
}
MPI_Barrier(MPI_COMM_WORLD);
MPI_Win window;
startTime = MPI_Wtime();
MPI_Win_create(buffer, bufferSize, sizeof(char), MPI_INFO_NULL, MPI_COMM_WORLD, &window);
endTime = MPI_Wtime();
MPI_Win_fence(0, window);
printf("\nMPI_Win_create time at %s = %lf", (my_rank == ORIGIN)?"ORIGIN":"TARGET", endTime-startTime);
MPI_Win_free(&window);
if (buffer) delete[] buffer;
MPI_Finalize();
}
推荐阅读
- c - 有没有办法在 Windows 上使用带有 clang 9.0.0 版本的 VS 2010?
- r - 无法编译 test.tex。调试技巧见 https://yihui.name/tinytex/r/#debugging。有关更多信息,请参阅 test.log。执行停止
- python - 圆整数解的算法?
- javascript - 有没有办法在不点击绘图控制器上的“编辑形状”的情况下使用 Leaflet.Draw 编辑传单形状?
- java - 在 Appium 上启动会话时如何解决此错误?
- python - 使用模板覆盖更改 django 管理列表中的模型对象 url
- lsof - 了解 lsof 输出中的 TYPE
- spring - 从需要密钥库的 Springboot 应用程序自动向服务器发送 Post 请求
- jms - 拒绝访问资源:type=
, application=JMSModule, destinationType=queue, resource=test, action=receive - c++ - 意外调用移动构造函数