計算PI的方法
1.tan(PI/4)=1 => PI=4arctan1。知道arctan1轉化爲定積分的形式是什麼吧。
利用arctan(x)的冪級數展開式,可以手工地計算PI
另外也可以採用正式手工計算PI
#include<stdio.h>
#include<time.h>
#define N 1000000
main(){
doublelocal,pi=0.0,w;
longi;
w=1.0/N;
clock_tt1=clock();
for(i=0;i<N;i++){
local=(i+0.5)*w;
pi=pi+4.0/(1.0+local*local);
}
clock_tt2=clock();
printf("PI is %.20f\n",pi*w);
printf("Time: %.2f seconds\n",(float)(t2-t1)/CLOCKS_PER_SEC);
}
orisun@orisun-desktop:~/Program$ ./PI1
PI is 3.14159265358976336202
Time: 0.02 seconds
2.以座標原點爲形心,作半徑爲1的圓和邊長爲2的正方形。正方形與圓的面積之比即爲PI
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#define N 1000000
main(){
longi,sum;
doublex,y;
srand((unsigned)time(NULL));
sum=0;
clock_tt1=clock();
for(i=0;i<N;i++){
x=(double)rand()/RAND_MAX;
y=(double)rand()/RAND_MAX;
if(x*x+y*y<1)
sum++;
}
clock_tt2=clock();
printf("PI is %.20f\n",4*(double)sum/N);
printf("Time: %.2f\n",(float)(t2-t1)/CLOCKS_PER_SEC);
}
orisun@orisun-desktop:~$ ./PI0
PI is 3.14301599999999980994
Time: 0.16
對比可以看到方法1在計算精度和速度上都具有絕對的優勢。在下面的openMP和MPI計算中我們都採用方法1。
OpenMP
OpenMP[OMP]是一個編譯器指令和庫函數的集合(已包含在gcc中),它用於爲共享存儲器計算機創建並行程序。OMP組合了C、C++和Fortran。
#include<stdio.h>
#include<time.h>
#include<omp.h>
#define N 1000000
main(){
doublelocal,pi=0.0,w;
longi;
w=1.0/N;
clock_tt1=clock();
#pragma omp parallel for private(local) reduction(+:pi)
for(i=0;i<N;i++){
local=(i+0.5)*w;
pi=pi+4.0/(1.0+local*local);
}
clock_tt2=clock();
printf("PI is %.20f\n",pi*w);
printf("Time: %.2f seconds\n",(float)(t2-t1)/CLOCKS_PER_SEC);
}
orisun@orisun-desktop:~/Program$ ./PI2
PI is 3.14159265358976336202
Time: 0.02 seconds
跟串行計算結果是一模一樣。
#pragma omp parallel表示下面的一行代碼或代碼塊要分配到多個執行單元中並行計算。
#pragma omp parallel for用在一個for循環的前面
private(local)默認情況下定義在並行代碼之外的變量爲各並行的執行單元所共享,使用private限制,表示每個執行單元創建該變量的一個副本
reduction(+:pi)表示並行代碼執行完畢後對各個執行單元中的pi進行相加操作。
MPICH2
ubuntu下首先下載mpich.tar.gz,然後按照常規的軟件安裝方法(configure、make、make install)安裝mpi就可以了。
MPI(Message Parsing Interface)消息傳遞接口是用於分佈式存儲器並行計算機的標準編程環境。MPI的核心構造是消息傳遞:一個進程將信息打包成消息,並將該消息發送給其他進程。MPI最常用的兩個實現是LAM/MPI[LAM]和MPICH[MPI]。
在MPI中執行單元(UE)指的就是進程。
MPI_BCAST(buffer,count,datatype,root,comm) IN/OUT buffer 通信消息緩衝區的起始地址(可變) IN count 通信消息緩衝區中的數據個數(整型) IN datatype 通信消息緩衝區中的數據類型(句柄) IN root 發送廣播的根的序列號(整型) IN comm 通信子(句柄)
MPI_REDUCE(sendbuf,recvbuf,count,datatype,op,root,comm) IN sendbuf 發送消息緩衝區的起始地址(可變) OUT recvbuf 接收消息緩衝區中的地址(可變,僅對於根進程) IN count 發送消息緩衝區中的數據個數(整型) IN datatype 發送消息緩衝區的元素類型(句柄) IN op 歸約操作符(句柄) IN root 根進程序列號(整型) IN comm 通信子(句柄)orisun@orisun-desktop:~/Program$ mpicc -o PI3 PI3.c %使用mpicc編譯
orisun@orisun-desktop:~/Program$ mpirun -np 4 ./PI3 %指定number of processor爲4
Processor 0 of 4 on orisun-desktop
please give n=Processor 2 of 4 on orisun-desktop
Processor 1 of 4 on orisun-desktop
Processor 3 of 4 on orisun-desktop
1000000
PI is 3.14159465358887635134
Time: 0.012510
orisun@orisun-desktop:~/Program$ mpdcleanup
時間是0.01251秒,比0.02秒明顯減少。
注意輸出中有這麼一行:please give n=Processor 2 of 4 on orisun-desktop
這說明是我們不能保證代碼中的18行和20行的執行順序。
背誦
世界記錄是100000位,日本人原口證於2006年10月3日背誦圓周率π至小數點後100000位。
普通話用諧音記憶的有“山巔一寺一壺酒,爾樂苦煞吾,把酒吃,酒殺爾,殺不死,樂而樂”,就是3.1415926535897932384626。 另一諧音爲:“山巔一石一壺酒,二侶舞仙舞,罷酒去舊衫,握扇把市溜”,就是3.14159265358979323846。
主要內容來自:http://www.cnblogs.com/zhangchaoyang