为什么单个线程比使用pthread的Ubuntu中的多线程更快?

时间:2015-01-12 10:46:16

标签: c++ c linux multithreading

XUbuntu 14.04,2个处理器。

多线程费用为0.8秒,而单线程费用仅为0.4秒。

如果定义了MULTI_THREAD,则程序将在单个线程中运行。否则,它是一个多线程程序

出了什么问题?

 ----------------code------------------------------

    #include <pthread.h>
    #include <semaphore.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>

    #define MULTI_THREAD
    #define NUM             10000
    #define SEM_M           10
    int arr[NUM];
    FILE *f;

        typedef struct _SemData{
            sem_t           sem_full;
            sem_t           sem_empty;
        }SemData;

        void InitSemData(SemData *sd){
            sem_init(&sd->sem_full,0,0);
            sem_init(&sd->sem_empty,0,SEM_M);
        }

        void DestroySemData(SemData *sd){

                sem_destroy(&sd->sem_full);
                sem_destroy(&sd->sem_empty);
            }

            void *Produce(void* data){
            #ifdef MULTI_THREAD
                SemData* psd=(SemData*)data;
            #endif
                int i;
                for(i=0;i<NUM;++i){
            #ifdef MULTI_THREAD
                    sem_wait(&psd->sem_empty);
            #endif
                        arr[i]=i;
                        fprintf(f,"produce:%d\n",arr[i]);
            #ifdef MULTI_THREAD
                    sem_post(&psd->sem_full);
            #endif
                }
            }

        void *Custom(void* data){
        #ifdef MULTI_THREAD
            SemData* psd=(SemData*)data;
        #endif
            int i,j;
            for(i=0;i<NUM;++i){
        #ifdef MULTI_THREAD
                sem_wait(&psd->sem_full);
        #endif
                    int tmp=0;
                    for(j=0;j<NUM;++j){
                        tmp+=arr[i];
                    }
                    arr[i]=tmp;
                    fprintf(f,"Custom:%d\n",arr[i]);
        #ifdef MULTI_THREAD
                sem_post(&psd->sem_empty);
        #endif
            }
        }

        void main(){
            f=fopen("b.txt","w");
            clock_t start=clock();
        #ifdef MULTI_THREAD
            SemData sd;
            InitSemData(&sd);

            pthread_t th0,th1;
            pthread_create(&th0,NULL,Produce,(void*)&sd);
            pthread_create(&th1,NULL,Custom,(void*)&sd);

            pthread_join(th0,NULL);
            pthread_join(th1,NULL);

            DestroySemData(&sd);
        #else
            Produce(NULL);
            Custom(NULL);
        #endif
            printf("TotalTime:%fs\n",((float)(clock()-start))/CLOCKS_PER_SEC);
            fclose(f);
        }

3 个答案:

答案 0 :(得分:3)

通常,并行化会带来额外的成本。您必须进行通信以分发和收集数据。此外,同步可能非常昂贵。

答案 1 :(得分:1)

您的单线程代码的工作方式如下:

  1. 制作所有数字
  2. 消耗所有数字
  3. 多线程代码的工作原理如下:

    Producer                             Consumer
    --------                             --------
    Produce one number                   Wait for a number to be produced
    Wait for a number to be consumed     Consume one number
    Produce one number                   Wait for a number to be produced
    Wait for a number to be consumed     Consume one number
    Produce one number                   Wait for a number to be produced
    Wait for a number to be consumed     Consume one number
    ...
    

    正如您所看到的,一次只有一个线程实际上在做任何事情 如果没有信令和上下文切换的开销,这将花费与单线程代码大致相同的时间,但由于信号和上下文切换非常昂贵,因此速度要慢得多。

    即使您重写了多线程代码以首先生成所有数字然后使用它们,它也会更慢,因为这与单线程代码 plus 完全相同信号和上下文切换。

答案 2 :(得分:0)

您正在测试的算法不需要在多个线程中被破解以提高效率:您必须考虑到创建新线程(即分配一些资源,等待同步等)总是有开销。 您必须评估新线程创建开销和单线程复杂性之间的权衡。