Fortran Coder

标题: 请教下面这段代码的差异 [打印本页]

作者: dypang    时间: 2018-1-8 11:24
标题: 请教下面这段代码的差异
大家好,我的程序里面有这么一段代码:

[Fortran] 纯文本查看 复制代码
     do j=1,nt
      ! csum=G_0t(j)
      do ic0=1,ndims
       ! CP0(j,ic0)=CP0(j,ic0)*csum
       CP0(j,ic0)=CP0(j,ic0)*G_0t(j)
      enddo
     enddo


其中 nt 是比较大的数,比如,640000。以上的代码可以 run。但是如果把上面的注释去掉,像下面这样:
[Fortran] 纯文本查看 复制代码
     do j=1,nt
      csum=G_0t(j)
      do ic0=1,ndims
       CP0(j,ic0)=CP0(j,ic0)*csum
       ! CP0(j,ic0)=CP0(j,ic0)*G_0t(j)
      enddo
     enddo


想来这样会减少对 G_0t 这个数组的内存的访问。但是这样会出现运行时错误,说 segmentation fault。

看起来这两种方式对内存的处理是不一样的。有没有高手帮我解释一下?

谢谢!
作者: pasuka    时间: 2018-1-8 11:51
csum没有定义吧?改成associate也出错?
[Fortran] 纯文本查看 复制代码
do j=1,nt
       associate(csum=>G_0t(j))then
      do ic0=1,ndims
       CP0(j,ic0)=CP0(j,ic0)*csum
      enddo
     end associate
     enddo

作者: dypang    时间: 2018-1-8 12:24
pasuka 发表于 2018-1-8 11:51
csum没有定义吧?改成associate也出错?
do j=1,nt
       associate(csum=>G_0t(j))then

谢谢。不过, csum 是声明成复数类型了的,因此应该不是这个原因
作者: pasuka    时间: 2018-1-8 13:17
本帖最后由 pasuka 于 2018-1-8 13:19 编辑
dypang 发表于 2018-1-8 12:24
谢谢。不过, csum 是声明成复数类型了的,因此应该不是这个原因

无法提供能够重现错误的最小代码,实在爱莫能助了
非涉密项目,可以考虑加入qq群,然后加群主好友,再远程桌面查看一下
本论坛官方QQ群:2338021


作者: dypang    时间: 2018-1-9 13:48
pasuka 发表于 2018-1-8 13:17
无法提供能够重现错误的最小代码,实在爱莫能助了
非涉密项目,可以考虑加入qq群,然后加群主好友,再远程 ...

谢谢。我问这个问题只是想了解一下fortran的更细致的规则。这两段代码,一般情况下应该是一样的。可是,在我这里,第二种方式确实就会出现段错误。我怀疑是这两种方式对内存的操作是不一样的。但是这种错误大概只是在数组非常大的情况下才会出现。

作者: dypang    时间: 2018-1-9 13:49
dypang 发表于 2018-1-9 13:48
谢谢。我问这个问题只是想了解一下fortran的更细致的规则。这两段代码,一般情况下应该是一样的。可是, ...

实际上,同样的程序,在 Linux 下面用第二种方式也是可以的,但是在 Windows 10 下面就不行。所以,应该跟操作系统也有关系。
作者: pasuka    时间: 2018-1-9 14:36
dypang 发表于 2018-1-9 13:48
谢谢。我问这个问题只是想了解一下fortran的更细致的规则。这两段代码,一般情况下应该是一样的。可是, ...

欲知更细的规则,请先把本站的教学视频看三遍
此外,Fortran静态方式开辟大数组在Linux下okay,在Windows下出错,往往与Fortran规则无关,与操作系统和编译原理有关
Windows下有可能是栈溢出,需要改成动态数组,也可能是32位非服务器版Windows系统的单进程2GB内存限制
希望活学活用,立竿见影,还是加群主QQ,远程桌面查找问题源头

作者: fcode    时间: 2018-1-11 17:51
从语法层次,两段代码是完全一样的。
但具体编译器实现,可能就不一样了。(与操作系统的区别应该无关,而和编译器有关,只是恰好你两个操作系统使用不同的编译器而已)
(注意,类似 gfortran for windows 和 gfortran for linux,我们视为不同的编译器)

就像,“把箱子搬到楼上”和“把箱子搬到上一层”
在中文里,两者是一样的。
但具体不同的人去执行它,就可能有区别。比如A某可能用双手抱,而B某用肩膀扛。

需要更多的代码细致的调试分析,甚至不排除是编译器的bug。
作者: dypang    时间: 2018-1-17 22:36
是的,大概跟编译器有关系,都是 pgfortran,但是一个是 windows 下面的版本,一个是 Linux 下面的版本。

作者: chiangtp    时间: 2018-5-2 15:27
你是否有確定不是 array subscript(s) out-of-bounds 的問題?
Segmentation faul:t - invalid memory reference?

在 compile-time options 若為 optimization, runtime 是不會 check 是否發生 array subscript(s) out-of-bounds
請用 non-optimization 試試




欢迎光临 Fortran Coder (http://bbs.fcode.cn/) Powered by Discuz! X3.2