使用蒙特卡罗模拟多线程计算 Pi

Posted

技术标签:

【中文标题】使用蒙特卡罗模拟多线程计算 Pi【英文标题】:calculating Pi with Monte Carlo Simulation Multithreaded 【发布时间】:2018-05-19 19:04:22 【问题描述】:

所以,我目前正在进行蒙特卡洛模拟以计算 Pi。我目前有 5 种不同的场景:500、20000、100000、1000000、10000000 点来计算 Pi,我的问题是我必须对算法进行多线程处理(每个点数有 2、4、6 和 8 个线程)但我已经一直在搜索多线程,但不明白我必须做什么才能实现我的目标。 希望有人能解释我或告诉我如何实际执行算法的多线程位。

代码如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>


int main () 


 int circ, total, i;
 double a, x, y, pi;

 a = 0;
 i = 0;

 total = 500;
 circ = 0;
 for ( i = 0; i<total; i++ ) 
  x = (double)rand ()/ RAND_MAX;
  y = (double)rand ()/ RAND_MAX;
  a = x*x + y*y
  if (a<=1) circ ++;
  
 pi = (double)circ/total * 4;
 printf ("For %d points, pi is %g \n", total, pi);

 total = 20000;
 circ = 0;
 for ( i = 0; i<total; i++ ) 
  x = (double)rand ()/ RAND_MAX;
  y = (double)rand ()/ RAND_MAX;
  a = x*x + y*y
  if (a<=1) circ ++;
  
 pi = (double)circ/total * 4;
 printf ("For %d points, pi is %g \n", total, pi);


 total = 100000;
 circ = 0;
 for ( i = 0; i<total; i++ ) 
  x = (double)rand ()/ RAND_MAX;
  y = (double)rand ()/ RAND_MAX;
  a = x*x + y*y
  if (a<=1) circ ++;
  
 pi = (double)circ/total * 4;
 printf ("For %d points, pi is %g \n", total, pi);


 total = 1000000;
 circ = 0;
 for ( i = 0; i<total; i++ ) 
  x = (double)rand ()/ RAND_MAX;
  y = (double)rand ()/ RAND_MAX;
  a = x*x + y*y
  if (a<=1) circ ++;
  
 pi = (double)circ/total * 4;
 printf ("For %d points, pi is %g \n", total, pi);

 total = 10000000;
 circ = 0;
 for ( i = 0; i<total; i++ ) 
  x = (double)rand ()/ RAND_MAX;
  y = (double)rand ()/ RAND_MAX;
  a = x*x + y*y
  if (a<=1) circ ++;
  
 pi = (double)circ/total * 4;
 printf ("For %d points, pi is %g \n", total, pi);

非常感谢您的耐心等待,祝您有美好的一天:)

【问题讨论】:

你试过什么?您是否尝试过一步一步地遵循 C 多线程教程? 【参考方案1】:

在编写程序或算法的多线程版本时,首先要考虑的是

    您必须首先确定应用程序的哪些部分会 享受多线程或需要并行运行。哪个是为了 循环代码部分

    您希望并行化的代码部分或分支必须是 彼此独立,以避免诸如竞争条件之类的事情。和 从您的代码中可以看出, 享受多线程的潜在代码分支在此 条件。

    a = x * x + y * y; if ( a <= 1 ) circ++;

    如果您想出此代码的多线程版本,您将不得不处理诸如竞争条件之类的事情,因为所有线程都希望同时写入a 共享内存。即使您尝试让每个线程专门写入共享内存,您最终可能会遇到另一个问题,这可能是您的代码的串行版本比并行版本快得多,原因可能是一个线程循环很长时间持有一个锁,它阻止其他线程访问a共享内存。尝试使用无锁机制(例如原子)也会导致内存排序等问题

你应该做什么

你现在应该做的是重新设计你的代码,让循环不会有任何依赖关系,或者如果你准备好面对多线程的危险而不重新设计你的代码,你可以看看这本书,它有一个学习pthreads和omp的部分。这是一本不错的书,但大多数示例无法编译取决于您使用哪种 c 标准进行编译

Darryl Gove - Multicore Application Programming for Windows, Linux, and Oracle Solaris - 2010

【讨论】:

以上是关于使用蒙特卡罗模拟多线程计算 Pi的主要内容,如果未能解决你的问题,请参考以下文章

Python蒙特卡罗计算圆周率PI——Numpy性能优化

数学模型:4. 蒙特卡罗模拟

计算机博弈 蒙特卡洛模拟

php 算法2 TIEA211计算pi蒙特卡罗方法

Python圆周率 Pi (π) 的计算(蒙特卡罗法+公式法)

蒙特卡洛方法计算pi