Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 与主程序位于同一文件中相比,子程序位于单独的模块中时,开销较大_Performance_Fortran_Compiler Optimization - Fatal编程技术网

Performance 与主程序位于同一文件中相比,子程序位于单独的模块中时,开销较大

Performance 与主程序位于同一文件中相比,子程序位于单独的模块中时,开销较大,performance,fortran,compiler-optimization,Performance,Fortran,Compiler Optimization,我正在评估fortran程序中某些功能的开销(以挂钟时间为单位)。我在GNU fortran中遇到了以下行为,这是我没有预料到的:将子例程与主程序放在同一个文件中(在包含区域或模块中),与将子例程放在单独的模块中(在单独的文件中)相比,会产生很大的影响 复制该行为的简单代码是: 我有一个子程序,可以将矩阵向量相乘250000次。在第一个测试中,我在主程序的包含区域中有一个子例程。在第二个测试中,相同的子例程位于单独的模块中。 两者在性能上的差异很大 主程序包含区域中的子例程运行10次 min:

我正在评估fortran程序中某些功能的开销(以挂钟时间为单位)。我在GNU fortran中遇到了以下行为,这是我没有预料到的:将子例程与主程序放在同一个文件中(在包含区域或模块中),与将子例程放在单独的模块中(在单独的文件中)相比,会产生很大的影响

复制该行为的简单代码是: 我有一个子程序,可以将矩阵向量相乘250000次。在第一个测试中,我在主程序的包含区域中有一个子例程。在第二个测试中,相同的子例程位于单独的模块中。 两者在性能上的差异很大

主程序包含区域中的子例程运行10次

min: 1.249
avg: 1.266
1.275 - 1.249 - 1.264 - 1.279 - 1.266 - 1.253 - 1.271 - 1.251 - 1.269 - 1.284
min: 1.848
avg: 1.861
1.848 - 1.862 - 1.853 - 1.871 - 1.854 - 1.883 - 1.810 - 1.860 - 1.886 - 1.884
子例程在单独的模块中运行10次

min: 1.249
avg: 1.266
1.275 - 1.249 - 1.264 - 1.279 - 1.266 - 1.253 - 1.271 - 1.251 - 1.269 - 1.284
min: 1.848
avg: 1.861
1.848 - 1.862 - 1.853 - 1.871 - 1.854 - 1.883 - 1.810 - 1.860 - 1.886 - 1.884
大约慢50%,这个因素似乎与矩阵的大小一致 以及迭代次数。 这些测试使用gfortran 4.8.5进行。使用gfortran 8.3.0,程序运行速度稍快,但从主程序的contain部分的子例程到单独模块中的子例程的时间加倍

波特兰集团在我的测试程序中没有这个问题,而且它的运行速度甚至比gfortran的最佳案例还要快

如果我从输入文件(或运行时命令行arg)读取矩阵的大小并进行动态分配,那么挂钟时间的差异就会消失,两种情况下的运行速度都会变慢(单独模块中子程序的挂钟时间,单独文件)。如果在主程序的编译时知道矩阵的大小,我怀疑gfortran能够更好地优化主程序

GNU编译器不喜欢我做错了什么,或者GNU编译器做得不好?在这种情况下,是否有编译标志来帮助gfortran

一切都是通过优化-O3编译的

代码(test_simple.f90)

作为

./simple

至少在我的测试计算机上,标志
-march=native
-flto
的组合是问题的解决方案。有了这些选项,程序将得到充分优化,并且子例程与主程序位于同一文件中或位于单独的文件(单独的模块)中没有区别。此外,运行时与使用Portland Group编译器的运行时相当。这些选择中的任何一个都无法解决问题
-march=native
单独使用会加快内置版本的速度,但会使模块版本更差

我的偏见是,
-march=native
选项应该是默认的;做其他事情的用户经验丰富,知道他们在做什么,因此他们可以添加适当的选项或禁用默认选项,而普通用户不会轻易想到它


感谢您的所有评论。

阅读有关-flto选项的文档。@evets,我阅读了关于-flto的内容,虽然它可以解决问题,但不幸的是,它没有。Bummer。在axpy_循环中,您可以获得整个程序优化,包括内衬-flto可允许axpy_回路情况实现更好的优化。最后,在我的系统上,-march=native产生了更大的影响。@steve,你在搞什么。-march=native和-ftlo的组合解决了这个谜团,使挂钟接近波特兰集团-march=仅本机就可以加快包含中的版本,但会使模块版本更差。如果您不介意,请花点时间写一个答案。默认情况下,GFortran会对同一文件中的过程进行各种过程间优化(不断传播和内联是常见的大胜利)。要跨多个(对象)文件获得这样的优化,您需要-flto。
./simple