在FORTRAN中插入NOP指令

3
C中,我会使用asm("nop");来插入内联的NOP指令。然而,我找不到在FORTRAN中实现此操作的方法。是否有强制编译器生成NOP的方法?我使用gfortran。原因是当我调用MPI_Finalize时,我的MPI程序会发生段错误,但当我在MPI_Finalize之前插入print *, ''或者sleep(1)命令时却不会。为了进一步分析此行为,我想在此调用前插入一个NOP指令来查看是否仍然会出现段错误。 编辑:我不确定为什么会有人对这个问题进行负评和关闭请求。经过进一步搜索,这个问题类似于Fortran中MPI_FINALIZE()导致的段错误

2
你尝试过打开所有运行时检查(-fcheck=all)编译和运行吗?你可能也需要使用-g。你描述的行为通常是由于你写入了一些不应该写入的内存,这些检查可以帮助你找到这样的情况 - 尽管在MPI代码中不能保证。 - Ian Bush
@IanBush 我默认使用 -fcheck=all 和 -ggdb。编译是干净的。 - Karthik Nishanth
是的,我应该这样做。然而,我仍然不理解sleepprint如何完全避免segfault。 - Karthik Nishanth
它可以修复它,因为它会在内存中更改程序的布局,以防止您破坏立即导致错误的内容,并且可能产生了一些更加微妙和隐匿的影响。 - Ian Bush
1个回答

1

似乎 segfault 是由于我假设MPI_Finalize(IERR) 中的 IERR 是可选参数引起的。当我提供一个参数时,它就不会崩溃了。

为了内联 NOP,我编写了一个 C 函数,并在 Fortran 中使用了 BIND C 来创建一个接口。

C 函数

void noop(long n)
{
    while (--n > 0)
        __asm__("nop");
}

FORTRAN接口

interface
    subroutine nop_inline(n) bind(c, name="noop")
        use ISO_C_BINDING, only: c_long
        implicit none
        integer (c_long), value :: n
    end subroutine nop_inline
end interface

仍然很奇怪的是,printfsleep如何能够防止segfault,但调用NOP 1E8次却没有。

我很高兴接受任何关于这种行为的解释作为答案。


@High Performance Mark 真巧啊!我看到了你在 https://stackoverflow.com/questions/11564951/segmentation-fault-during-mpi-finalize-in-fortran 上的评论,并用 use mpi 替换了所有的 includes。谢谢。 - Karthik Nishanth
1
只是一个非常牵强的猜测...也许printf/sleep在堆栈上留下了一些垃圾,这些垃圾作为finalize的有效参数。 - Ped7g

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接