《多核程序设计》学习笔记:蒙特卡洛法串行与并行求解π值

最近学习了蒙特卡洛求π的算法,自己实现了串行与并行算法。

(1)串行算法

算法思想:产生2n个随机数据,范围[0,1],对每个数据点计算其坐标是否满足,统计满足此关系的点的数量count,则 π=count/4n。

代码:

#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
#define n 1000000000
void main()
{
    int i,count=0;
    double x,y,pi;
    srand((int)time(NULL));
    for(i=0;i<n;i++)
    {
        x=(double)(1.0*rand()/RAND_MAX); //产生0-1的随机数
		y=(double)(1.0*rand()/RAND_MAX);
        if(pow(x,2)+pow(y,2)<=1)
        {
            count+=1;
        }
    }
    pi=4.0*count/n;
    printf("%f",pi);
}

(2)并行算法

算法思想:

1.       确定需要产生的点的个数n,参与运行的处理器数m;

2.       对每一个处理器,生成两个随机数x,y,范围[0,1];

3.       判断两个随机数x,y是否满足;

4.       若满足,则变量COUNTi++;

5.       重复步骤2-4,直至每个处理器均生成n/m个随机点;

6.       收集COUNTi的值,并累加至变量COUNT中,此即为随机点落在圆弧内的数量;

7.       计算π的值。

代码:

//#include"stdafx.h"
#include<windows.h>
#include<stdio.h>
#include<time.h>
#include<math.h>
#define POINT_NUM 10000000000//点的数目,尽量不适用N、M这些会出现命名冲突
#define THREAD_NUM 10                //线程数
DWORD Thread(int *pData)
{
    double x,y;
    srand(time(NULL));
    for(int i=0;i<POINT_NUM/THREAD_NUM;i++)
    {
        x=(double)(1.0*rand()/RAND_MAX); //产生0-1的随机数
        y=(double)(1.0*rand()/RAND_MAX);
        if(pow(x,2)+pow(y,2)<=1.0)               //满足范围
            (*pData)+=1;
    }
    printf("点数:%d\n",*pData);
    return 0;
}
int main(int argc,char* argv[])
{
    double pi;
    int count[THREAD_NUM]; 
    int total=0;
    HANDLE h[THREAD_NUM];
    printf("每个:%d\n",POINT_NUM/THREAD_NUM);
    for(int i=0;i<THREAD_NUM;i++)
    {
        count[i]=0;
        h[i]=CreateThread(NULL,
                            0,
                            (LPTHREAD_START_ROUTINE) Thread,
                            &count[i],
                            0,
                            NULL);
        if(h[i]==NULL)
            printf("CreateThread Thread%d Error!\n",i);
            Sleep(1000);   //若不sleep,则会出现各线程产生的点数一样的情况   
    }
    WaitForMultipleObjects(THREAD_NUM,h,TRUE,INFINITE);
    for(i=0;i<THREAD_NUM;i++)
        total+=(count[i]);
    printf("总数:%d\n",total);
    pi=4.0*total/POINT_NUM;
    printf("pi:%f\n",pi);             //注意输出格式
    return 0;
}

       将生成点的数目写的非常大,并在两个程序中分别加上时间函数,输出算法运行时间(如下的两张图,分别为串行和并行算法的运行结果截图),从中可以看出在生成的总点数相同的前提下,两算法的精度相差不大,但并行算法的效率更高。



  • 2
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值