gpt4 book ai didi

c - 使用串行和多线程实现程序蒙特卡罗计算pi

转载 作者:行者123 更新时间:2023-12-03 12:58:33 26 4
gpt4 key购买 nike

当我实现蒙特卡罗方法的解决方案来计算 pi 数时,其中以圆心为中心的圆具有坐标 (0,0) ,半径为1,内接于正方形,给定公式如下:pi = 4 * (number of points in circle) / (total number of points ) .我使用 2 个程序实现了该解决方案 serial.c (单进程)和 multithread.c (多线程进程)来比较这两种解决方案的执行速度。

程序serial.c

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

void circle_point();
static long int total_point;
static long int count_circle=0;
clock_t start_time, end_time;

int main(int argc, char *argv[]){
if(argc==1){
printf("Enter number point\n");
return -1;
}

if(argc!=2){
printf("Argument is wrong\n");
return -1;
}
total_point=atoll(argv[1]);

start_time=clock();
circle_point();
double pi=4.0*(double)count_circle/(double)total_point;
end_time=clock();

printf("PI = %17.15f\n",pi);
printf("Time to compute= %g second\n",(double)(end_time-start_time)/CLOCKS_PER_SEC);
return 0;
}

void circle_point(){
srand(time(NULL));
int i;
for(i=0;i<total_point;i++){
double x= (double)rand()/(double)RAND_MAX;
double y=(double)rand()/(double)RAND_MAX;
double r= sqrt(x*x+y*y);
if(r<=1) count_circle+=1;
}
}

程序多线程.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <pthread.h>

#define NUM_THREAD 4

void* circle_point(void *param);

pthread_t tid[NUM_THREAD]={0};
int count[NUM_THREAD]={0};
clock_t start_time, end_time;
static long int total_point;
static long int count_circle=0;


int main(int argc, char const *argv[]){
if(argc==1){
printf("Enter number point\n");
return -1;
}

if(argc!=2){
printf("Argument is wrong\n");
return -1;
}

total_point=atoll(argv[1])/NUM_THREAD;

start_time= clock();
srand(time(NULL));
static int i;
for(i=0; i<NUM_THREAD;i++)
pthread_create(&tid[i],NULL,circle_point,&count[i]);
for(i=0;i<NUM_THREAD;i++){
pthread_join(tid[i],NULL);
count_circle+=count[i];
}
double pi=4.0*(double)count_circle/(double)total_point/(double)NUM_THREAD;
end_time=clock();

printf("PI = %17.15f\n",pi);
printf("Time to compute= %g second\n",(double)(end_time-start_time)/CLOCKS_PER_SEC);
return 0;
}

void* circle_point(void *param){
int *pcount= (int*)param;
int i;
for(i=0; i<total_point;i++){
double x= (double)rand()/(double)RAND_MAX;
double y=(double)rand()/(double)RAND_MAX;
double r= sqrt(x*x+y*y);
if(r<=1) *pcount=*pcount+1;
}
pthread_exit(0);
}

我遇到的问题是在总点数相同的情况下输入,例如 10^7 ,串口的执行速度为 0.45 seconds而多线程的执行速度是 6.06 seconds ,与其他输入类似,串行的执行时间总是大于多线程。我不明白我遇到了什么问题?因为从理论上讲,多线程会比串行执行得更快,所以实际上有没有像我遇到的那样串行执行速度比多线程快的情况。

最佳答案

单线程:

void circle_point(){
srand(time(NULL));
int i;
for(i=0;i<total_point;i++){
double x= (double)rand()/(double)RAND_MAX;
double y=(double)rand()/(double)RAND_MAX;
double r= sqrt(x*x+y*y);
if(r<=1) count_circle+=1;
}
}

多线程:
void* circle_point(void *param){
int *pcount= (int*)param;
int i;
for(i=0; i<total_point;i++){
double x= (double)rand()/(double)RAND_MAX;
double y=(double)rand()/(double)RAND_MAX;
double r= sqrt(x*x+y*y);
if(r<=1) *pcount=*pcount+1;
}
pthread_exit(0);

我猜你用的是同样的 total_point对于多线程程序的每个线程,就像在单线程中一样(这意味着在这两种情况下,第二个程序中的每个线程都是 total_point = 10^7)。所以在多线程程序中,你用 NUM_THREAD * total_point来计算点。你可以试试 NUM_THREAD = 1 ,两种情况下的执行时间相似(第二个程序可能稍高一些)。或者您可以测量每个线程的执行时间来验证这一点。

如果要比较两个程序的速度,就得让多线程程序计算出和单线程一样的总点数。例如,第一个线程计算 10^7/4点,然后第二个线程计算 10^7/4积分等等。

理论上,多线程程序可以比顺序程序更快地完成,因为它所做的一些工作可以同时进行。在所有处理器上花费的时间总和将高于顺序版本(因为添加了协调的东西),但从开始到结束所用的时间可能更短。

关于c - 使用串行和多线程实现程序蒙特卡罗计算pi,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61951442/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com