4

假设地说,如果我的科学工作是在开发功能/模块/子程序(在台式机上),我需要知道什么才能将其整合到在超级计算机(可能模拟分子)上运行的大规模模拟中、流体、反应等)?

我的印象是,它与尽可能利用某些库(例如,BLAS、LAPLACK)、修改算法(减少迭代)、分析、并行化、考虑内存-硬盘-处理器的使用/访问有关……我是意识到这句格言,“想要优化你的代码?不要这样做”,但如果有人有兴趣学习编写高效的代码,可以参考哪些参考资料?

我认为这个问题与语言无关,但由于许多用于生物分子模拟、气候建模等的数字运算包是用 Fortran 的某个版本编写的,所以这种语言可能是我感兴趣的目标(而且我在 Fortran 中进行了相当广泛的编程77)。

4

4 回答 4

5

并行化将是关键。

由于您引用的问题(例如 CFD、多物理场、传质)通常表示为大规模线性代数问题,因此您需要能够很好地并行化的矩阵例程。MPI 是这些类型问题的标准。

物理学也会产生影响。例如,可以使用显式动力学和人工质量和阻尼矩阵有效地解决一些椭圆问题。

3D 多物理场意味着具有不同时间尺度的耦合微分方程。您将需要一个精细的网格来解决空间和时间上的细节,因此自由度的数量会迅速增加;时间步长将取决于您的问题的稳定性要求。

如果有人想出如何将线性代数作为 map-reduce 问题来运行,他们就会把它敲掉。

于 2011-08-13T23:12:34.247 回答
5

在任何级别的机器中,剖析都是必须的。在常见的用法中,我发现扩展到越来越大的网格需要更好地理解网格软件和网格的拓扑结构。从这个意义上说,你学到的关于优化一台机器的一切仍然适用,但是了解网格软件会让你获得更多的里程。Hadoop 是最流行和广泛使用的网格系统之一,因此了解调度程序选项、接口(API 和 Web 接口)以及使用的其他方面将有所帮助。尽管您可能不会将 Hadoop 用于给定的超级计算机,但它是学习分布式计算的一种不那么痛苦的方法。对于并行计算,你可能会追求 MPI 和其他系统。

此外,学习在单台机器上跨多个内核或处理器并行化代码是您可以在台式机上开始学习的东西。

建议:

  1. 学习在单机上优化代码:
    • 学习分析
    • 学习使用优化的库(分析后:让你看到加速)
    • 确保您非常了解算法和数据结构 ( * )
  2. 学习在多核机器上进行令人尴尬的并行编程。
    • 稍后:考虑多线程编程。这更难,可能不会为您的问题带来回报。
  3. 了解用于分布式处理的基本网格软件
  4. 了解网格上的并行处理工具
  5. 学习为替代硬件编程,例如 GPU、各种专业计算系统。

这与语言无关。我不得不在多种语言和多个 HPC 系统中学习相同的序列。在每一步,采取更简单的路线来学习一些基础设施和工具;例如,在多线程之前学习多核,在并行之前学习分布式,这样您就可以看到哪些适合硬件和问题,哪些不适合。

某些步骤可能会根据本地计算实践、已建立的代码库和导师重新排序。如果你有一个大型的 GPU 或 MPI 库,那么一定要学习它,而不是把 Hadoop 强加给你的合作者。

( * ) 非常了解算法的原因是,只要您的代码在网格上运行,其他人就会看到它。当它占用系统时,他们会想知道你在做什么。如果您正在运行一个多项式并且应该是常数的过程,您可能会发现自己被嘲笑了。其他具有更多领域专业知识的人可能会帮助您找到 NP-hard 问题的良好近似值,但您应该知道这个概念是存在的。

于 2011-08-13T23:17:04.560 回答
5

假设地说,如果我的科学工作是在开发功能/模块/子程序(在台式机上),我需要知道什么才能将其整合到在超级计算机(可能模拟分子)上运行的大规模模拟中、流体、反应等)?

首先,您需要了解问题所在。并非所有问题都可以并行解决(我使用并行一词的含义尽可能广泛)。那么,看看现在问题是如何解决的。能不能用其他方法更快解决。能不能分割成独立的部分……等等……

Fortran 是专门用于科学计算的语言,近年来,随着新语言功能的发展,针对这个“市场”的功能也有了一些非常有趣的发展。术语“co-arrays”可能是一个有趣的读物。

但就目前而言,我建议先阅读《使用 OpenMP 》之类的书——OpenMP 是一个更简单的模型,但该书(里面的 fortran 示例)很好地解释了基础知识。消息解析接口(给朋友,MPI :) 是一个较大的模型,也是常用的模型之一。OpenMP 的下一步可能应该朝这个方向发展。关于 MPI 编程的书籍并不罕见。

你还提到了图书馆——是的,你提到的一些图书馆被广泛使用。其他的也可以。恕我直言,一个不确切知道性能问题出在哪里的人永远不要尝试承担尝试重写库例程的任务。

还有一些关于并行算法的书籍,你可能想看看。

我认为这个问题与语言无关,但由于许多用于生物分子模拟、气候建模等的数字运算包是用 Fortran 的某个版本编写的,所以这种语言可能是我感兴趣的目标(而且我在 Fortran 中进行了相当广泛的编程77)。

简而言之,它归结为理解问题,了解性能问题在哪里,用不同的方法重新解决整个问题,迭代几次,到那时你已经知道你在做什么,并且你被困在哪里。

于 2011-08-14T00:34:26.550 回答
3

我们的处境与你相似。我最同意@Iterator 的回答,但我认为还有更多要说的。

首先,我相信通过随机暂停方法进行“分析”,因为我对测量事物并不感兴趣(这样做很容易),但我对找出导致时间浪费的代码感兴趣,所以我可以修复它. 这就像泛光灯和激光之间的区别。

例如,我们使用 LAPACK 和 BLAS。现在,在获取堆栈样本时,我看到很多样本都在比较字符的例程中。这是从乘法和缩放矩阵的一般例程中调用的,并且是从我们的代码中调用的。矩阵操作例程,为了灵活,有字符参数来告诉它,如果矩阵是下三角形或其他什么。事实上,如果矩阵不是很大,例程可以花费超过 50% 的时间来对问题进行分类。当然,下次从同一个地方调用它时,它会再次做同样的事情。在这种情况下,应该编写一个特殊的例程。当它被编译器优化时,它会尽可能快,并且会节省所有的分类时间。

再举一个例子,我们使用各种 ODE 求解器。当然,这些都被优化到第 n 级。它们通过调用用户提供的例程来计算导数和可能的雅可比矩阵来工作。如果这些用户提供的例程实际上并没有做太多,那么样本确实会在 ODE 求解器本身中显示程序计数器。但是,如果用户提供的例程做得更多,示例将主要在这些例程中找到堆栈的低端,因为它们花费的时间更长,而 ODE 代码花费的时间大致相同。因此,优化应该集中在用户提供的例程中,而不是 ODE 代码中。

一旦您完成了堆栈采样所确定的几种优化,这可以将速度提高1-2 个数量级,然后如果问题允许,请务必利用并行性、MPI 等。

于 2011-08-14T17:47:50.623 回答