实现程序Monte Carlo计算pi使用串行和多线程

问题描述 投票:1回答:1

[当我为蒙特卡洛方法实现解决方案以计算pi数时,其中以中心为圆的圆具有坐标(0,0),半径为1并刻在正方形中,给定的公式如下:pi = 4 *(圈中的点数)/(总点数)。我使用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;
    }
}

程序multithread.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秒,而多线程的执行速度为6.06秒,类似于其他输入,执行时间串行数总是大于多线程。我不明白我遇到了什么问题?因为从理论上讲,多线程将比串行执行更快,所以实际上在任何情况下串行都比多线程执行得更快。

c multithreading operating-system pthreads montecarlo
1个回答
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;
    }
}

多线程:

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点,依此类推。

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

© www.soinside.com 2019 - 2024. All rights reserved.