《多核程序設計》學習筆記:蒙特卡洛法串行與並行求解π值

最近學習了蒙特卡洛求π的算法,本身實現了串行與並行算法。算法

(1)串行算法windows

算法思想:產生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)並行算法線程

算法思想:code

1.       肯定須要產生的點的個數n,參與運行的處理器數m;ip

2.       對每個處理器,生成兩個隨機數x,y,範圍[0,1];it

3.       判斷兩個隨機數x,y是否知足;io

4.       若知足,則變量COUNTi++;class

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;

}

將生成點的數目寫的很是大,並在兩個程序中分別加上時間函數,輸出算法運行時間(以下的兩張圖,分別爲串行和並行算法的運行結果截圖),從中能夠看出在生成的總點數相同的前提下,兩算法的精度相差不大,但並行算法的效率更高。

相關文章
相關標籤/搜索