我有一个Fortran程序,该程序可以在armflang
级别与-O3
一起使用,但是可以在-Ofast
优化级别使用segfaults。可能出什么问题了?
更新:问题并非特定于工作负载。对于某些NCAR工作负载和WRF 3.9.1,会发生这种情况。
答案 0 :(得分:0)
这可能是由于-fstack-arrays
级默认启用的-Ofast
选项所致。根据Arm Fortran编译器armflang documentation,-fstack-arrays
级别未启用-O3
。
-fstack-arrays
选项在本地堆栈上放置各种大小的自动数组。这通常会带来更好的性能,因为它避免了对本地数组和临时数组的间接调用malloc()
和free()
。在典型的Linux系统上,默认情况下,每个进程的堆栈大小默认为8192 kB(通常可以增加,因为硬限制是“无限”)。这给大型数组的程序带来了问题,导致了非显而易见的段错误。
有两种方法可以解决此问题
使用-Ofast -fno-stack-arrays
代替,这将禁止在本地堆栈上放置自动数组,但保留所有其他-Ofast
优化。
如果系统允许,请在运行程序之前调用ulimit -s unlimited
。这样会将堆栈设置为大于默认大小。
答案 1 :(得分:0)
没有MWE,在提出问题之前您已经有了答案!
您对-Ostack与-fstack-arrays的选择感到惊讶。我一直在审查本地和自动阵列在单线程和多线程方面的堆栈性能与堆性能
我的经验是,对于堆栈溢出的情况,即对于较大的数组,将大型数组放在堆栈上没有明显的优势。小型阵列确实显示出一些性能优势,特别是如果它们可以驻留在缓存中。 必须认识到位于堆栈中的数组大小,因为更健壮的解决方案是针对堆上的较大数组。
对于多线程,其中每个线程都有自己的堆栈,我展示了一些增加线程堆栈大小并将所有数组放在单独堆栈上的好处。在我的测试中,这似乎可以减少内存一致性问题,尽管结论性的结论可能难以捉摸。
我会对您选择-Ofast和-fstack-arrays的推理感兴趣。您是否对放置在堆栈中的本地和自动阵列测试了大小限制?