Fortran与C:曼德博集合基准测试

13 浏览
0 Comments

Fortran与C:曼德博集合基准测试

我偶然发现了基准测试游戏(代码页面)并比较了Fortran和C语言。我对曼德博集合测试中计算时间的差异感到非常惊讶(Fortran慢了4.3倍!),因为这两种语言具有非常相似的特性集。\n此外,Fortran应该能够进行更激进的优化(参见例如\"Fortran相对于C在重计算中更容易优化吗?\")。 \n有人能解释一下Fortran缺少哪些功能,以获得类似C示例中的速度吗?(似乎位运算在这里提升了代码性能。)\n编辑:这不是关于哪种编程语言更好的问题(总有很多方面起作用)。这更是一个关于优化差异的基本问题。 \n


\n附加说明(由Peter Cordes添加):有一篇关于Fortran应用程序向量化基础的论文,其中也简要讨论了Fortran编程中的SIMD。对于英特尔编译器:Fortran中的显式向量编程

0
0 Comments

Fortran与C++:曼德博集合基准测试的原因及解决方法

在这个基准测试中,C++版本是手动进行向量化的,使用SIMD指令(SSE,AVX或AVX512)进行x86优化,比如使用_mm256_movemask_pd(v1 <= v2);来获取整个向量比较结果的位掩码,让它一次性检查4个像素是否超出边界。并且使用GNU C本地向量语法进行SIMD乘法等操作,比如r2 + i2用于使用普通C/C++运算符对SIMD向量进行加法或乘法。

C++版本的循环条件针对SIMD进行了优化:

// 对包含8个复数值的向量进行50次曼德博集合计算。
// 偶尔检查迭代结果是否超出无法回归的点(> 4.0)。

而Fortran版本仅仅使用OpenMP进行自动并行化,编译器的自动向量化不会产生和手动调优循环条件一样好的结果,因为后者比更频繁地进行检查更加廉价。


还有很多C和C++版本的程序与Fortran版本的速度相似。对于没有手动进行向量化的C/C++源代码来说,它们的性能相当。

我不确定Intel Fortran或其他编译器是否支持手动向量化的扩展。

我明白了!你提到的最后一点应该是我的问题…非常感谢你的努力。

所以基本上是用C语法伪装的汇编代码。

: 你知道Fortran也可以做到这一点吗?

: 可以说是,但是编译器可以自由地优化内部函数调用。你也可以说a+baddsd xmm0, xmm1的伪装。C语言被设计为一种可移植的汇编语言,其中每个表达式/运算符对应硬件可以用一两条指令完成的操作。如果你把内部函数调用看作是现代CPU提供的新操作的新运算符,它们并没有那么特殊。编译器仍然可以展开它们、优化它们,或者将_mm_add_pd(_mm_mul_pd(), x)优化成一个FMA指令。(gcc和clang会这样做,但MSVC和ICC将内部函数调用更多地看作汇编语言。)

_winzig: 有一种未记录的方法可以在Intel Fortran中调用与特定x86_64指令相关的内部函数调用(如果感兴趣,请搜索DEC$ ATTRIBUTES KNOWN_INTRINSIC),但不能调用使用向量寄存器的指令。Fortran中没有这些指令所需的数据类型。

0