我正在为Fortran mpi程序编写异步负载均衡器。我使用MPI_TESTANY来检查MPI_IRECV调用的完整性,使用MPI_WTIME来测量执行时间。 您可以在https://github.com/hachat/mpi-pi-calc/blob/experiment/source/load_balancer.f
找到完整的代码下面给出了第207到217行,我遇到了这个奇怪的问题。
...
ELSE IF(PENDING_RECVS .GT. 0) THEN
PRINT *,'8ST:', START_TIME(1),' TASK:',TASK
CALL MPI_TESTANY(NUMTASKS-1,REQUEST_RECV_RES,
& TASK,RECV_TEST_FLAG,STATUS_RECV_RES,IERR)
IF (IERR .NE. MPI_SUCCESS) THEN
PRINT *,'ERROR IN WAIT FOR RECV RESPONSE. TERMINATING.'
CALL MPI_ABORT(MPI_COMM_WORLD, 1, IERR)
END IF
PRINT *,'9ST:', START_TIME(1),' TASK:',TASK
...
以上代码的输出如下:(对于两个进程)
...
6ST:1388151838.3635089
7ST:1388151838.3635089
1ST:1388151838.3635089
8ST:1388151838.3635089任务:1
9ST:6.2921131024483548E-316任务:1
10ST:6.2921131024483548E-316
11ST:6.2921131024483548E-316
...
在8ST打印和9ST打印之间,START_TIME(1)变量已更改!我尝试更改怀疑缓冲区溢出的START_TIME变量的名称和位置,但此结果没有变化。
任何帮助都将不胜感激。
答案 0 :(得分:2)
始终使用IMPLICIT NONE
以强制编译器检查是否已显式声明所有变量。
STATUS_RECV_RES
未明确声明,因此编译器会创建隐式REAL
变量。由于REAL
不足以容纳整个整数MPI状态数组,因此当MPI_TESTANY
找到已完成的请求时,部分堆栈会被覆盖。只是你的编译器将START_TIME
数组放在STATUS_RECV_RES
附近并且前者的第一个元素被覆盖成为受害者。
大多数编译器也不会按照声明的顺序放置堆栈变量(或任何变量)。这通常是出于性能原因和对齐要求而完成的。