50

随着 C++ 编译器(尤其是 intel 编译器)的快速发展,以及在 C/C++ 代码中直接应用 SIMD 函数的能力,Fortran 在数值计算领域是否仍然具有真正的优势?

我来自应用数学背景,我的工作涉及大量数值分析、计算、优化等,并具有严格定义的性能要求。

我对 Fortran 几乎一无所知,我在 C/CUDA/matlab 方面有一些经验(如果您一开始就认为后者是一门计算机语言),而且我的日常任务涉及分析非常大的数据(例如 10GB 大矩阵),并且似乎该程序至少将 2/3 的时间用于内存访问(这就是我将其部分工作发送到 GPU 的原因),你们认为我至少尝试 fortran 例程可能值得吗?我的代码中的一些性能关键部分来提高我的程序的性能?

因为那里涉及的复杂性和事情需要完成,所以如果只有那里有显着的性能优势,我只会执行该例程,在此先感谢。

4

5 回答 5

59

与 C++ 相比,Fortran 具有严格的别名语义,并且几十年来一直在积极调整数值性能。使用 CPU 处理数据数组的算法通常有可能从 Fortran 实现中受益。

编程语言大战不应被太认真地对待,但在 15 个基准测试中,Fortran 在其中四个(英特尔 Q6600 单核)上的速度排名第一,超过任何其他单一语言。您可以看到 Fortran 最出色的基准是大量数字基准:

反例:

  • k-核苷酸慢 500%(这个基准主要关注更复杂的数据结构和字符串处理,这不是 Fortran 的强项)

您还可以看到一个摘要页面“慢多少倍”,它表明在所有实现中,Fortran 代码平均最接近每个基准测试的最快实现——尽管分位数条比 C++ 大得多,表明 Fortran不适合 C++ 擅长的某些任务,但你应该已经知道了。

所以你需要问自己的问题是:

  1. 这个函数的速度是否如此重要,以至于在 Fortran 中重新实现它值得我花时间?

  2. 性能如此重要,以至于我在学习 Fortran 上的投资会得到回报吗?

  3. 是否可以使用像 ATLAS 这样的库而不是自己编写代码?

回答这些问题需要详细了解您的代码库和业务模型,因此我无法回答这些问题。但是,是的,Fortran 实现通常比 C++ 实现更快。

您决定的另一个因素是示例代码的数量和可用的参考实现的数量。Fortran 的悠久历史意味着有大量的数字代码可供下载,甚至可以访问图书馆。与往常一样,您需要筛选它才能找到好东西。

于 2012-10-25T23:55:20.867 回答
16

您的问题的完整和正确答案是,“是的,Fortran 确实具有一些优势”。

C++ 也有一些不同的优点。Python、R 等也是如此。它们是不同的语言。用一种语言做一些事情,用另一种语言做一些事情会更容易、更快捷。所有这些都在他们的社区中被广泛使用,并且有很好的理由。

在没有更具体的问题的情况下,其他任何事情都只是噪音和语言战争的诱饵,这就是为什么我投票结束这个问题并希望其他人也能这样做。

于 2012-10-26T00:51:25.770 回答
8

Fortran 自然适合数值编程。在这样的程序中,您往往会有大量的数字,通常是排列好的数组。数组是 Fortran 中的一等公民,将数值内核从 Matlab 转换为 Fortran 通常非常简单。关于潜在的性能优势,请参阅其他答案,它们很好地涵盖了这一点。基线可能是您可以使用当今大多数编译语言创建高效的数值应用程序,但您可能会跳过一些循环才能到达那里。由于语言特性,Fortran 经过精心设计,允许编译器识别大多数优化点。当然,您也可以使用任何编译语言(包括 Fortran)编写任意慢速代码。在任何情况下,您都应该选择合适的工具。Fortran 适合数值应用,C适合系统相关的开发。最后,学习 Fortran 基础并不难,学习其他语言总是值得的。这为您要解决的问题打开了不同的视图。

于 2012-10-26T00:18:24.407 回答
8

另外值得一提的是,Fortran 比 C++ 更容易掌握。事实上,Fortran 的语言规范比普通 C 语言规范更短,而且它的语法可以说更简单。你可以很快拿起它。

这意味着如果您只对学习 C++ 或 Fortran 感兴趣以解决您目前遇到的单个特定问题(例如,加快您用原型语言编写的内容的瓶颈),Fortran 可能会给您带来更好的投资回报.

于 2016-10-22T12:39:52.850 回答
1

Fortran 代码通常更适合矩阵和向量类型的操作。但是您也可以通过将提示/建议传递给编译器以产生类似质量的向量指令,从而使用 c/c++ 代码产生类似的性能。一个给我很大提升的选择是不假设作为数组对象的输入变量之间存在内存别名。通过这种方式,编译器可以积极地为 IL​​P 进行内部循环展开和流水线操作,其中它可以使用正确的预取在循环迭代中重叠加载和存储操作。

于 2017-10-18T20:10:54.773 回答