我有两个使用
Monte-Carlo method计算pi的实现:有线和无线程.没有线程工作的实现很好,但带线程的方法在准确性和性能方面存在问题.这是代码:
没有线程:
#include <stdio.h> #include <stdlib.h> #include <time.h> int main() { srand(time(NULL)); unsigned long N = 0,Nin = 0; float x,y; while(N < 2E+9) { x = rand()/((float)RAND_MAX + 1.0)*10.0 - 5.0; y = rand()/((float)RAND_MAX + 1.0)*10.0 - 5.0; if(x*x + y*y < 25.0) Nin += 1; N++; } long double pi = 4.0 * (long double)Nin / (long double)N; printf("\tPi1: %.20Lf\n\t%lu %lu\n",pi,Nin,N); return 0; }
并有线程:
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <pthread.h> typedef struct { unsigned long Nin; unsigned long N; } nums; void pi_counter(nums* a) { float x,y; unsigned int N = 0,Nin = 0; while(N < 1E+9) { x = rand()/((float)RAND_MAX + 1.0)*10.0 - 5.0; y = rand()/((float)RAND_MAX + 1.0)*10.0 - 5.0; if(x*x + y*y < 25.0) Nin++; N++; } a -> Nin += Nin; a -> N += N; } int main() { pthread_t thread1,thread2,thread3; nums a; srand(time(NULL)); pthread_create( &thread1,NULL,pi_counter,&a ); pthread_create( &thread2,&a ); pthread_join( thread1,NULL ); pthread_join( thread2,NULL ); long double pi = 4.0 * (long double)a.Nin / (long double)a.N; printf("\tPi2: %.20Lf\n\t%lu %lu\n",a.Nin,a.N); return 0; }
结果:
$time ./pi2 Pi2: 3.14147154999999999995 1570735775 2000000000 real 1m1.927s user 1m23.624s sys 0m0.139s $time ./pi Pi1: 3.14158868600000000006 1570794343 2000000000 real 0m49.956s user 0m49.887s sys 0m0.022s
我的错误在哪里?