我最近从实验科学背景转向计算生物物理学。到目前为止,我正在学习基础知识并在我的台式电脑上对 LJ 流体进行一些基本的蒙特卡罗模拟。但是,当我尝试在集群上运行我的代码时,它的速度与我的桌面相同或更低。后来,我的实验室伙伴告诉我编写适合并行计算的代码。我不知道该怎么做。是否有任何资源,书籍针对那些不是很精通计算机科学的人,可以教他们这种编程的基础知识和必要的工具。我在 C++ 上编写了代码,我也愿意转向 fortran。
为分子计算编写并行代码
正如评论中提到的,一本关于科学计算的 C++ 并行编程的好、简单的书/资源已经为学习并行编程的更一般问题提供了答案。
话虽如此,如果您决定继续学习并行编程,一个简单的 Lennard-Jones Monte Carlo 程序可能不是一个糟糕的尝试项目。OpenMP 方法相对容易理解和实现。许多编译器都有一个 -fopenmp 标志,它将打开pragma代码中任何 OpenMP 的处理。一个典型的例子pragma是应用于一个for循环(或在 Fortran 中,一个do循环),以在并行线程之间划分迭代。例如,如果你想总结个数字,并且你有个线程可用,每个线程可以总结(大约)的数字,并行,然后结果可以在最后组合。您需要首先学习一些基本的 OpenMP 概念:变量private和shared变量之间的差异,以及至关重要的reduction变量的概念,它将保存求和的结果。但是在这个级别上掌握 OpenMP 并不需要太长时间。
关键是,在最简单的蒙特卡洛程序中,耗时的部分正是这样一个循环。当您考虑移动一个原子时,您需要计算移动前后它与所有其他原子之间的 Lennard-Jones 对势的总和。这假设您有一个相对较小的系统,并且没有使用复杂的技术(例如域分解/邻居列表)来加快速度。基本上,如果您可以并行化一个简单的求和循环,那么并行化单粒子势能计算并不是一个巨大的延伸。
在您的集群上,很可能每个节点都包含多个可以访问相同内存的内核:如果是这样,那么您可以使用 OpenMP 在单个节点上运行,每个线程对应于其中一个内核。因此,原则上,在最佳情况下,您可能会获得每个节点有多少内核的加速。
对于更大规模的 Monte Carlo,可能需要更复杂的方法。可以并行化大规模的 Monte Carlo 代码(例如,通过使用域分解和编写使用 MPI 的程序),但比这个简单的 OpenMP 示例更繁琐且需要更多注意(因为需要确保详细的平衡)。
如果您决定以这种方式进行,您绝对应该首先跟进上面提到的一些资源。但是在你学习了基础知识之后,实际上只是在一个简单的程序中插入几行额外的行来总结一组数字,作为测试,然后对你的代码做类似的事情,然后编译适当的选项。