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

XUbuntu 14.04,2个处理器。

multithreading成本0.8s,而单线程成本只有0.4s。

如果定义了MULTI_THREAD ,那么程序将在单个线程中运行。 否则,这是一个multithreading程序

怎么了?

  ----------------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); } 

你的单线程代码是这样工作的:

  1. 产生所有的数字
  2. 消耗所有的数字

多线程代码的工作原理是这样的:

 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 ... 

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

即使你重写了你的多线程代码来产生所有的数字,然后消耗它们,速度也会变慢,因为这与单线程代码加上信号和上下文切换完全一样。

一般而言,并行会带来额外的成本。 你必须沟通分发和收集数据。 另外同步可能非常昂贵。

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