为什么我在这个程序中没有看到多线程的任何加速?

时间:2017-01-27 19:57:40

标签: c multithreading performance debugging pthreads

我有这个功能。它递归地计算曲线下的竞技场。它在具有两个核心的计算机上运行。

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然而它&#39 ;并不比仅仅在一个线程上运行更快(将threads设置为1),实际上它有点慢。

为什么它不快两倍?任何帮助整理出来将非常感谢。感谢。

2 个答案:

答案 0 :(得分:0)

对于多线程来说这是一个足够大的问题吗?也许创建新线程和管理锁的开销大于使用单个线程解决问题的成本。

答案 1 :(得分:0)

您的处理器可能有多个核心,但您的floating point coprocessor呢?它可能没有,并且会在另一个线程执行FPU计算时阻塞每个线程。

另外,请参阅此文章:

  

同时多线程无益处的工作负载是大多数单个软件线程在处理器或内存中使用大量任何资源的工作负载。例如,浮动密集型的工作负载很可能从同步多线程中获得很少,并且最有可能失去性能。这些工作负载大量使用浮点单元或内存带宽。具有低CPI和低缓存未命中率的工作负载可能会带来一些小的好处。

Source