Fortran 与 C:Mandelbrot 基准测试
Fortran vs C: Mandelbrot benchmark
我偶然发现了 Benchmark Game (code page) 并比较了 Fortran 和 C。我对 Mandelbrot 测试的计算时间差异感到非常惊讶(Fortran 慢了 4.3 倍!) 因为这两种语言具有非常相似的功能集。
此外,Fortran 应该能够优化更彻底(参见 "Is Fortran easier to optimize than C for heavy calculations?")。
能否解释一下 Fortran 中缺少哪些功能才能获得速度,例如在 C 示例中? (似乎位操作 here 正在提升代码。)
编辑:这不是哪种编程语言更好的问题(总是有很多方面在起作用)。在这个例子中,这是一个关于优化差异的基本问题。
Peter Cordes 的回答的附加内容:有一篇关于 Basics of Vectorization for Fortran Applications which also shortly discusses SIMD in Fortran programming. For Intel compilers: Explicit Vector Programming in Fortran
的论文
该基准站点上获胜的 C++ 版本是 x86 手动矢量化,使用 SIMD 内在函数(SSE、AVX 或 AVX512) ,例如使用 _mm256_movemask_pd(v1 <= v2);
获取整个比较结果向量的位掩码,让它并行检查 4 个像素是否越界。以及用于 SIMD 乘法等的 GNU C 本机向量语法,例如 r2 + i2
使用普通 C / C++ 运算符添加或乘以 SIMD 向量。
C++ 版本有一个针对 SIMD 优化的循环条件:
// Do 50 iterations of mandelbrot calculation for a vector of eight
// complex values. Check occasionally to see if the iterated results
// have wandered beyond the point of no return (> 4.0).
Fortran 仅使用 OpenMP 进行自动并行化,编译器的自动矢量化不会创建任何与手动调整的循环条件一样好的东西,该循环条件一直在做源代码没有的冗余工作(因为这比更频繁地检查便宜)。
该程序有很多 C 和 C++ 版本,它们的速度与 Fortran 版本相似。它们对于 C/C++ 源代码来说非常均匀不是手动矢量化的。
我不确定英特尔 Fortran 或任何其他编译器是否支持手动矢量化扩展。
我偶然发现了 Benchmark Game (code page) 并比较了 Fortran 和 C。我对 Mandelbrot 测试的计算时间差异感到非常惊讶(Fortran 慢了 4.3 倍!) 因为这两种语言具有非常相似的功能集。 此外,Fortran 应该能够优化更彻底(参见 "Is Fortran easier to optimize than C for heavy calculations?")。
能否解释一下 Fortran 中缺少哪些功能才能获得速度,例如在 C 示例中? (似乎位操作 here 正在提升代码。)
编辑:这不是哪种编程语言更好的问题(总是有很多方面在起作用)。在这个例子中,这是一个关于优化差异的基本问题。
Peter Cordes 的回答的附加内容:有一篇关于 Basics of Vectorization for Fortran Applications which also shortly discusses SIMD in Fortran programming. For Intel compilers: Explicit Vector Programming in Fortran
的论文该基准站点上获胜的 C++ 版本是 x86 手动矢量化,使用 SIMD 内在函数(SSE、AVX 或 AVX512) ,例如使用 _mm256_movemask_pd(v1 <= v2);
获取整个比较结果向量的位掩码,让它并行检查 4 个像素是否越界。以及用于 SIMD 乘法等的 GNU C 本机向量语法,例如 r2 + i2
使用普通 C / C++ 运算符添加或乘以 SIMD 向量。
C++ 版本有一个针对 SIMD 优化的循环条件:
// Do 50 iterations of mandelbrot calculation for a vector of eight // complex values. Check occasionally to see if the iterated results // have wandered beyond the point of no return (> 4.0).
Fortran 仅使用 OpenMP 进行自动并行化,编译器的自动矢量化不会创建任何与手动调整的循环条件一样好的东西,该循环条件一直在做源代码没有的冗余工作(因为这比更频繁地检查便宜)。
该程序有很多 C 和 C++ 版本,它们的速度与 Fortran 版本相似。它们对于 C/C++ 源代码来说非常均匀不是手动矢量化的。
我不确定英特尔 Fortran 或任何其他编译器是否支持手动矢量化扩展。