回 帖 发 新 帖 刷新版面

主题:用grads把grib转成二进制后

我手上有一个用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个回复)

沙发


整个文件就一个数据类型?

板凳

我认为楼主的怀疑是对的。

顺序写的时候,在换行(写新纪录)的时候,编译器可能写入了某种字符,可能是回车,或者其他。

楼主可以做个实验就知道了,编译器的不同版本,比如gcc 4.1 和 4.5,同一个Fortran输出语句制造的数据文件都不一样大。

所以,顺序读写语句是依赖编译器的,不仅不能与随机读写语句兼容,甚至编译器的不同版本之间也不兼容。

3 楼

[quote]我认为楼主的怀疑是对的。

顺序写的时候,在换行(写新纪录)的时候,编译器可能写入了某种字符,可能是回车,或者其他。

楼主可以做个实验就知道了,编译器的不同版本,比如gcc 4.1 和 4.5,同一个Fortran输出语句制造的文件都不一样大。

所以,顺序读写语句是依赖编译器的,不仅不能与随机读写语句兼容,甚至编译器的不同版本之间也不兼容。[/quote]
这个倒是不很清楚
gcc4.5更改了.o的生成方式,以和现代方式兼容
看gfortran的svn,最近倒是经常改io

4 楼

楼上的高手,咱们说的不是同一个东西啊,

gcc 4.5引入了lto,链接时优化,也就是section合并成segment时,原先是没有优化的,现在的4.5有优化了,结果就是各个段在内存中的分布应该是更合理更聪明了,因为链接器只是个机器,它干什么是靠编译器指定的,也就是所谓的链接脚本。

但是这个只对多个子程序、多个文件以及制造库的时候更有效,不会影响段内部的执行效率的,对数值程序影响应该不会很大,所以对他兴趣不是太大。
楼上的朋友,不妨加-flto编译lapack玩玩,体验体验lto。直接的体验就是编译的慢了,尤其是最后制造库的时候。
以前看intel文档,他就吹过链接时优化,intel编译器早就支持这个了。

我上面说的东西是同一句Fortran源码,不同编译器版本,所写出来的东西不同。当然用同一个版本的编译器制造的可执行文件来读,结果是正确的,如果换了版本编译出来的程序来读那个文件,发生的事情正如一楼。

io对性能的影响一般有限,修修补补一般可以无视。只有f2008的什么并行io可能比较酷,因为io比cpu内存慢得多,任何高性能的程序都不应该让cpu等io,所以任何用于科学计算的程序语言都应该支持并行io.

以上都是我的看法,完全可能出错,大家姑妄看看吧~

5 楼

[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 楼

忘了,编译成动态的啊。lapack论坛上置顶了的。

7 楼

[quote]忘了,编译成动态的啊。lapack论坛上置顶了的。[/quote]
那也和静态后加-flto一样吧
因为ar后的.o还是保留link time的部分的
看看-flto生成的库体积就知道了

8 楼

建议楼主上传二进制文件的一部分上来。

9 楼

制造动态库的命令不是ar cr,

是gcc -shared -fPIC *.o -o libXXX.so

intel编译器带链接时优化编译lapack,制造库的时候,要等待好几分钟,如果我没记错。

10 楼

[quote]制造动态库的命令不是ar cr,

是gcc -shared -fPIC *.o -o libXXX.so

intel编译器带链接时优化编译lapack,制造库的时候,要等待好几分钟,如果我没记错。[/quote]
咱不是说的一个啊
我是说静态库的flto性能和动态库的应该差不多才对

-fPIC似乎合并进-shared了,如果我没记错的话

我来回复

您尚未登录,请登录后再回复。点此登录或注册