变量说明
(1)变量前缀为‘fortran’表示在Fortran中进行求和操作,且当后缀不为‘DFC’时表示为使用Fortran读取文件,数据类型为real*4;
(2)变量后缀为‘DFC’(data from c)表示为数据来自于C程序,数据类型为real*4;
(3)变量前缀为‘c’表示为使用C读取文件,数据类型为float,在C中进行求和操作;
(4)文件相同,读取位置相同,读取数据大小相同,共计1440万个float类型数据;
(4)数据最小值为1649.254272,最大值为12704.22168。
fortran_sum_float | 使用sum()对数据进行求和,结果存入real*4变量中 |
fortran_sum_double | 使用sum()对数据进行求和,结果存入real*8变量中 |
fortran_sum_auto_float | 自己编写sum()对数据进行求和,以real*4变量进行累加 |
fortran_sum_auto_double | 自己编写sum()对数据进行求和,以real*8变量进行累加 |
fortran_sum_float_DFC | 使用sum()对数据进行求和,结果存入real*4变量中 |
fortran_sum_double_DFC | 使用sum()对数据进行求和,结果存入real*8变量中 |
fortran_sum_auto_float_DFC | 自己编写sum()对数据进行求和,以real*4变量进行累加 |
fortran_sum_auto_double_DFC | 自己编写sum()对数据进行求和,以real*8变量进行累加 |
c_sum_auto_float | 自己编写sum()对数据进行求和,以real*4变量进行累加 |
c_sum_auto_double | 自己编写sum()对数据进行求和,以real*8变量进行累加 |
数据验证
编译器:mpiifort/ifort | 编译器:mpiicc | ||
VALUE | VALUE | ||
fortran_sum_float | 74177954000 | ||
fortran_sum_double | 74177953792 | ||
fortran_sum_auto_float | 74177954000 | c_sum_auto_float | 75781332992 |
fortran_sum_auto_double | 75781374529 | c_sum_auto_double | 75781374529 |
fortran_sum_float_DFC | 74177954000 | ||
fortran_sum_double_DFC | 74177953792 | ||
fortran_sum_auto_float_DFC | 74177954000 | ||
fortran_sum_auto_double_DFC | 75781374529 |
从数据可以看出不管是通过Fortran还是C进行文件读取,以double类型的变量进行累加后的结果一致,程序也对两组数据进行过一一比较,结果数据一致。
更换编译器
编译器:gfortran | 编译器:g++ | ||
VALUE | VALUE | ||
fortran_sum_float | 69373526000 | ||
fortran_sum_double | 69373526016 | ||
fortran_sum_auto_float | 69373526000 | c_sum_auto_float | 69373526016 |
fortran_sum_auto_double | 75781374529 | c_sum_auto_double | 75781374529 |
fortran_sum_float_DFC | 69373526000 | ||
fortran_sum_double_DFC | 69373526016 | ||
fortran_sum_auto_float_DFC | 69373526000 | ||
fortran_sum_auto_double_DFC | 75781374529 |
在更换编译器后,Fortran的sum求和以及自己编写的sum求和与之前对比都发生了变化,可见不同的编译器对float数据溢出存在不同的处理方式,由此将导致不同程度的精度损失。
以上测试Fortran代码与C代码在编译时都使用了-O3进行优化。
取消-O3代码优化
编译器:gfortran | 编译器:g++ | ||
VALUE | VALUE | ||
fortran_sum_float | 69373526000 | ||
fortran_sum_double | 69373526016 | ||
fortran_sum_auto_float | 69373526000 | c_sum_auto_float | 69373526016 |
fortran_sum_auto_double | 75781374529 | c_sum_auto_double | 75781374529 |
fortran_sum_float_DFC | 69373526000 | ||
fortran_sum_double_DFC | 69373526016 | ||
fortran_sum_auto_float_DFC | 69373526000 | ||
fortran_sum_auto_double_DFC | 75781374529 |
以上数据没有变化。
编译器:mpiifort/ifort | 编译器:mpiicc | ||
VALUE | VALUE | ||
fortran_sum_float | 69373526000 | ||
fortran_sum_double | 69373526016 | ||
fortran_sum_auto_float | 69373526000 | c_sum_auto_float | 75781332992 |
fortran_sum_auto_double | 75781374529 | c_sum_auto_double | 75781374529 |
fortran_sum_float_DFC | 69373526000 | ||
fortran_sum_double_DFC | 69373526016 | ||
fortran_sum_auto_float_DFC | 69373526000 | ||
fortran_sum_auto_double_DFC | 75781374529 |
从数据可以看出C的编译器不会因为-O3而改变对float数据溢出的处理方式,但mpiifort会受-O3的影响。
以最终结果存入real*8变量的情况进行对比,增加-O3后的Fortran的sum()求和后的相对误差由0.084557037下降为0.021158507。