【问题标题】:How to parellelize a program如何并行化程序
【发布时间】:2015-09-17 18:29:27
【问题描述】:

我是一名物理学研究员,我正在对锰酸盐的磁性进行蒙特卡罗模拟。我用 C 语言编写了一个程序,一切都很好,只是执行时间非常长(可能 1000 年,具体取决于马尔可夫链的大小和格的大小)。所以我没有解决方案,除了我必须并行化我的程序并找到一个超级计算器。当然,我不能并行化整个程序,因为如果这样做,我将失去马尔可夫链循环的因果关系。我只能在马尔可夫链中并行化一个循环,这就足够了。下面是我的程序的一部分,显示了我必须并行化的循环。如果有人能告诉我如何将此循环划分为线程?

n = 1;

while(n <= Nc)
{
    fscanf(voisins,"%d%d%f%f%f%f",&i,&j,&r[0],&r[1],&r[2],&d);
    V = 0.0;E = 0.0;F = 0.0;

    for(p = 0;p < 3;p++)
    {
        V += (D/pow(d,3.0))*(spin[3*i-3+p]-w[p])*spin[3*j-3+p];
        E += (spin[3*i-3+p]-w[p])*r[p];
        F += spin[3*j-3+p]*r[p];
    }

    G = -3*(D/pow(d,5.0))*E*F;
    dU += (V+G);
    n++;
}

【问题讨论】:

  • 你想知道如何多线程。 (查看英特尔 TBB 和 OpenMP);或者,您是否想知道如何将其拆分为更小的块,以便您可以使用您选择的库对其进行多线程处理?
  • 你的代码很慢,如图所示。 1. 你真的需要 fscanf() 吗? I/O 非常昂贵 2. pow(d, 3.0) -> (ddd) 3. pow(d, 5.0) -> (ddddd)。目前还不清楚GdU 是什么类型的值。全局变量?
  • 我真的需要 fscanf 来避免制表符。这个文件 voisins.dat 是 6 Go 大小的。 V,G,F,E 和 dU 是双精度数,并在 main() 函数中声明。是的,它非常慢,尤其是这个过程将重复数百万次以达到热平衡(中心极限定理)。除了并行计算,我别无选择

标签: c parallel-processing montecarlo


【解决方案1】:

这通常很困难,但众所周知,蒙特卡洛方法是可并行的。您可以从Pthread tutorial 开始,但有很多关于并行编程的书籍。

蒙特卡洛方法被广泛使用,例如核物理学(例如Tripoli 4)。

您还可以阅读有关Message Passing Interface (MPI) 的更多信息(甚至可能是Multi-Agent SystemsCloud computing

最近的C++11 & C++14 标准了解threads

如果您可以使用真正的超级计算机,您可能希望混合使用这些方法(因此变得困难;如果可能,请寻求专家的帮助):例如在每个 MPI 节点上使用多线程 MPI。

您或许可以考虑在 GPGPU 上使用例如矢量计算OpenCL。我不确定它是否适合蒙特卡洛方法(更适合像有限元这样的矩阵计算)。

OpenMP 在编译器的帮助下启用了一些有限的并行性(例如#pragma-s)。

不要忘记,存在大量用于 Monte Carlo 的高效并行库,因此也要研究它们。

您还可以考虑采用传统的IPC 的多进程方法(如果交换的数据不大,则可能是一些RPC 机制,例如Json-RPC)。然后阅读Advanced Linux Programming,了解更多关于fork(2)poll(2)pipe(7)tcp(7) & socket(7)shm_overview(7)sem_overview(7)、...

Parallel computing 很难(你需要很多年才能成为专家,而我不是),因为细节是邪恶的。

PS。当然,您需要在开发笔记本电脑或台式机上使用(并熟练使用)Linux。

【讨论】:

  • “并行计算很困难(你需要很多年才能成为专家,而我不是),因为细节是邪恶的。”一切都是真的……《高级 Linux 编程》也是一本非常好的读物。
猜你喜欢
  • 1970-01-01
  • 2019-06-27
  • 1970-01-01
  • 2020-09-01
  • 2020-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多