【发布时间】:2017-06-13 14:41:13
【问题描述】:
我有这个功能。它递归地计算曲线下的竞技场。它在具有两个内核的计算机上运行。
void* quad(void* argis){
struct args* arg=argis;
double m=(arg->l+arg->r)/2;
double fm=func(m);
double larea=(arg->fl+fm)*(m-arg->l)/2;
double rarea = (fm+arg->fr)*(arg->r-m)/2;
struct args* arg1 = (struct args*)malloc(sizeof(struct args));
arg1->l=arg->l;
arg1->r=m;
arg1->fl=arg->fl;
arg1->fr=fm;
arg1->area=larea;
struct args* arg2 = (struct args*)malloc(sizeof(struct args));
arg2->l=m;
arg2->r=arg->r;
arg2->fl=fm;
arg2->fr=arg->fl;
arg2->area=rarea;
if(fabs((larea+rarea)-arg->area)>error){
if(threads<=1){
void* p1=quad(arg1);
void* p2=quad(arg2);
larea=*((double*)p1);
rarea=*((double*)p2);
free(p1);
free(p2);
}
else{
pthread_t thread1, thread2;
pthread_mutex_lock(&lock1);
threads-=2;
pthread_mutex_unlock(&lock1);
pthread_create(&thread1, NULL, &quad, (void*)arg1);
pthread_create(&thread2, NULL, &quad, (void*)arg2);
void* ptr1;
void* ptr2;
pthread_join(thread1,&ptr1);
pthread_join(thread2,&ptr2);
larea=*(double*)ptr1;
rarea=*(double*)ptr2;
}
}
free(arg1);
free(arg2);
double ret= (larea+rarea);
double* poin=(double*)malloc(sizeof(double));
*poin=ret;
return poin;
}
现在,当我将 threads 变量设置为 2 时,它应该创建两个同时执行递归的新线程,我认为这就是这样做的,我对 Pi 有一个合理的估计,但它并不比运行更快在一个线程上(将 threads 设置为 1),实际上它有点慢。
为什么不是两倍快?任何帮助解决这个问题将不胜感激。谢谢。
【问题讨论】:
-
为什么你认为分割成线程会加速你的代码?你如何进行基准测试?哪个平台? minimal reproducible example 在哪里?哦,不要在 C 中转换
void *! -
编程很难。
-
从多个线程对共享对象的非只读、非原子、非同步访问的未定义行为。
-
不太明白。哪个对象是共享的并且需要同步?
-
@JohnWu:看看
if(threads<=1)和pthread_mutex_lock(&lock1); threads-=2; pthread_mutex_unlock(&lock1);。threads在一种情况下被访问而没有获取锁,因此锁不会阻止竞争。
标签: c multithreading performance debugging pthreads