我在fortran遇到MPI_REDUCE()的精度问题。我已经测试了两种方法来求和存储在每个节点上的双精度数。我使用的MPI_REDUCE()行是
call MPI_REDUCE(num,total,1,MPI_DOUBLE_PRECISION,MPI_SUM,0,MPI_COMM_WORLD,ierr)
存储每个核心上“num”值的总和,并将其发送到根核心上的“total”。
我使用的另一种方法涉及发送和接收
if (rank .eq. 0) total = num
do i = 1,nproc-1
if (rank .eq. i) call MPI_SEND(num,1,MPI_DOUBLE_PRECISION,0,&
100,MPI_COMM_WORLD,ierr)
if (rank .eq. 0) then
call MPI_RECV(num,1,MPI_DOUBLE_PRECISION,i,&
100,MPI_COMM_WORLD,stat,ierr)
total = total + num
end if
end do
后者总是给我相同的总数,而前者根据我使用的处理器数量产生不同的值(通常会改变1x10 ^ -5左右)。在所有情况下,ierr为0。我做错了吗?
由于
答案 0 :(得分:3)
浮点运算不是严格关联的,执行运算的顺序会对结果产生影响。而
(a+b)+c == a+(b+c)
对于真实(如数学,而不是Fortran,术语)数字而言,对于浮点数而言(普遍)并非如此。因此,内置减少产生的结果与您自己的家庭减少不同,这并不奇怪。当您改变处理器的数量时,您无法控制计算中各个添加的顺序;即使在固定数量的处理器上,我也不会对同一程序的不同执行结果之间的微小差异感到惊讶。相反,您自己的减少总是以相同的顺序添加。
两个结果的相对误差是多少? 10^(-5)
的数据仅告诉我们绝对误差,并且不允许我们得出结论,你的错误完全可以通过f-p算术的非相关性来解释。