主题:用grads把grib转成二进制后
bellanchor
[专家分:0] 发布于 2010-10-11 12:43:00
我手上有一个用grads把grib转成的二进制资料,221*256的格点,共120个时次,只有一个变量。
我用的是gfortran
分别用以下两段语句都能读出数据
open(1,file=fn,form='unformatted')
do t = 1, 120
read(1)((u(i,j,t),i=1,221),j=1,256)
enddo
-----------------------------------------------
open(1,file=fn,access='direct',recl=221*256*4)
do t = 1, 120
read(1,rec=t)((u(i,j,t),i=1,221),j=1,256)
enddo
但两组数据有差异,t=1的时候,两组数据的第一个值分别是-9.99E+008(缺省值),3.17E-040,然后下面的数全部错位。t=2的时候,第二段程序读出的数据出现了两个3.17E-040,下面的数错位更厉害。
另外就是想问一下,是不是sequential写入的二进制文件可以direct读出,但是direct写入的不能sequential读出?因为我感觉那个二进制像是顺序写入的,但为什么读出来不会出错只是值有点儿问题呢?
希望谁能帮助一下,谢谢
回复列表 (共15个回复)
沙发
jstzhurj [专家分:4680] 发布于 2010-10-11 13:44:00
整个文件就一个数据类型?
板凳
f2003 [专家分:7960] 发布于 2010-10-11 16:00:00
我认为楼主的怀疑是对的。
顺序写的时候,在换行(写新纪录)的时候,编译器可能写入了某种字符,可能是回车,或者其他。
楼主可以做个实验就知道了,编译器的不同版本,比如gcc 4.1 和 4.5,同一个Fortran输出语句制造的数据文件都不一样大。
所以,顺序读写语句是依赖编译器的,不仅不能与随机读写语句兼容,甚至编译器的不同版本之间也不兼容。
3 楼
dongyuanxun [专家分:7180] 发布于 2010-10-11 16:05:00
[quote]我认为楼主的怀疑是对的。
顺序写的时候,在换行(写新纪录)的时候,编译器可能写入了某种字符,可能是回车,或者其他。
楼主可以做个实验就知道了,编译器的不同版本,比如gcc 4.1 和 4.5,同一个Fortran输出语句制造的文件都不一样大。
所以,顺序读写语句是依赖编译器的,不仅不能与随机读写语句兼容,甚至编译器的不同版本之间也不兼容。[/quote]
这个倒是不很清楚
gcc4.5更改了.o的生成方式,以和现代方式兼容
看gfortran的svn,最近倒是经常改io
4 楼
f2003 [专家分:7960] 发布于 2010-10-11 16:26:00
楼上的高手,咱们说的不是同一个东西啊,
gcc 4.5引入了lto,链接时优化,也就是section合并成segment时,原先是没有优化的,现在的4.5有优化了,结果就是各个段在内存中的分布应该是更合理更聪明了,因为链接器只是个机器,它干什么是靠编译器指定的,也就是所谓的链接脚本。
但是这个只对多个子程序、多个文件以及制造库的时候更有效,不会影响段内部的执行效率的,对数值程序影响应该不会很大,所以对他兴趣不是太大。
楼上的朋友,不妨加-flto编译lapack玩玩,体验体验lto。直接的体验就是编译的慢了,尤其是最后制造库的时候。
以前看intel文档,他就吹过链接时优化,intel编译器早就支持这个了。
我上面说的东西是同一句Fortran源码,不同编译器版本,所写出来的东西不同。当然用同一个版本的编译器制造的可执行文件来读,结果是正确的,如果换了版本编译出来的程序来读那个文件,发生的事情正如一楼。
io对性能的影响一般有限,修修补补一般可以无视。只有f2008的什么并行io可能比较酷,因为io比cpu内存慢得多,任何高性能的程序都不应该让cpu等io,所以任何用于科学计算的程序语言都应该支持并行io.
以上都是我的看法,完全可能出错,大家姑妄看看吧~
5 楼
dongyuanxun [专家分:7180] 发布于 2010-10-11 16:34:00
[quote]楼上的高手,咱们说的不是同一个东西啊,
gcc 4.5引入了lto,链接时优化,也就是section合并成segment时,原先是没有优化的,现在的4.5有优化了,结果就是各个段在内存中的分布应该是更合理更聪明了。但是这个只对多个子程序、多个文件以及组建库的时候更有效,不会影响段内部的执行效率的,对数值程序影响应该不会很大,所以对他兴趣不是太大。
楼上的朋友,不妨加-flto编译lapack玩玩,体验体验lto。直接的体验就是编译的慢了,尤其是最后制造库的时候。
以前看intel文档,他就吹过链接时优化,intel编译器早就支持这个了。
我上面说的东西是同一句Fortran源码,不同编译器版本,所写出来的东西不同。当然用同一个版本的编译器制造的可执行文件来读,结果是正确的,如果换了版本编译出来的程序来读那个文件,发生的事情正如一楼。
io对性能的影响一般有限,修修补补一般可以无视。只有f2008的什么并行io可能比较酷,因为io比cpu内存慢得多,任何高性能的程序都不应该让cpu等io,所以任何用于科学计算的程序语言都应该支持并行io.[/quote]
lapack使用-flto真的 影响很小
原因是他的lib最后是ar 很多.o形成的,并没有链接
要想使用-flto的lapack
要在主程序编译和链接时使用-flto
不过我试了几个函数,速度都相差不大呢,可能大批量用才有效果吧
不过gcc4.5.x比gcc4.4.x编译出来的lapack库快很多
6 楼
f2003 [专家分:7960] 发布于 2010-10-11 16:35:00
忘了,编译成动态的啊。lapack论坛上置顶了的。
7 楼
dongyuanxun [专家分:7180] 发布于 2010-10-11 16:40:00
[quote]忘了,编译成动态的啊。lapack论坛上置顶了的。[/quote]
那也和静态后加-flto一样吧
因为ar后的.o还是保留link time的部分的
看看-flto生成的库体积就知道了
8 楼
jstzhurj [专家分:4680] 发布于 2010-10-11 16:41:00
建议楼主上传二进制文件的一部分上来。
9 楼
f2003 [专家分:7960] 发布于 2010-10-11 16:45:00
制造动态库的命令不是ar cr,
是gcc -shared -fPIC *.o -o libXXX.so
intel编译器带链接时优化编译lapack,制造库的时候,要等待好几分钟,如果我没记错。
10 楼
dongyuanxun [专家分:7180] 发布于 2010-10-11 16:54:00
[quote]制造动态库的命令不是ar cr,
是gcc -shared -fPIC *.o -o libXXX.so
intel编译器带链接时优化编译lapack,制造库的时候,要等待好几分钟,如果我没记错。[/quote]
咱不是说的一个啊
我是说静态库的flto性能和动态库的应该差不多才对
-fPIC似乎合并进-shared了,如果我没记错的话
我来回复