多线程在单核和多核CPU上的执行效率问题的讨论

zhangbinnpu 2009-09-02 04:37:54
测试函数的定义如下:
void TreadFuc1(PVOID param)
{
_int64 sum=0;
_int64 counter_begin,counter_end;
QueryPerformanceCounter((LARGE_INTEGER*)&counter_begin);
for(int i=0;i<100000000;i++)
{
sum+=i;
}
SetEvent(evet1);
}
void TreadFuc2(PVOID param)
{
_int64 sum=0;
_int64 counter_begin,counter_end;
QueryPerformanceCounter((LARGE_INTEGER*)&counter_begin);
for(int i=0;i<100000000;i++)
{
sum+=i;
}
SetEvent(evet2);
}


双核机器上的测试:DualCore Intel Pentium E2160, 1800 MHz (9 x 200)
测试1:开启两个线程同时分别执行TreadFuc1和TreadFuc2函数,测得执行完所花时间为0.451501s;顺序执行完 TreadFuc1和TreadFuc2函数,测得所花时间为0.850882s
测试2:指定测试只运行在一个核上,测试步骤按照测试1进行,所对应的测试结果分别为为0.870268s,0.883862s

单核机器上的测试:AMD 1600MHz
测试:开启两个线程同时分别执行TreadFuc1和TreadFuc2函数,测得执行完所花时间为0.967732s;顺序执行完 TreadFuc1和TreadFuc2函数,测得所花时间为0.958844s


结论:双核上的多线程明显可以提高程序性能,从0.451501s和0.850882s的时间对比就能看的出来
迷惑:为什么单核上的多线程性能提高并不明显呢?我预期的是并行执行比顺序执行要快很多,可是测试结果并不是这样





下面是测试代码,有兴趣的可以一起讨论和研究下
int main(int argc, char* argv[])
{


DWORD dwSet=1;
int p=SetProcessAffinityMask(GetCurrentProcess(),dwSet); //设置CPU的亲和力将dwSet的值分别设置为1,2,3看双核CPU的每个核的使用率

_int64 sum=0;
_int64 counter_begin,counter_end,large;

evet1=CreateEvent(NULL,FALSE,FALSE,NULL);
evet2=CreateEvent(NULL,FALSE,FALSE,NULL);
evet11=CreateEvent(NULL,FALSE,FALSE,NULL);
evet22=CreateEvent(NULL,FALSE,FALSE,NULL);

DWORD dwP1=0,dwS1=0,dwP2=0,dwS2=0;

QueryPerformanceFrequency((LARGE_INTEGER*)&large);


QueryPerformanceCounter((LARGE_INTEGER*)&counter_begin); //多线程并行执行部分
_beginthread(TreadFuc1,0,NULL);
_beginthread(TreadFuc2,0,NULL);
WaitForSingleObject(evet1,INFINITE);
WaitForSingleObject(evet2,INFINITE);
QueryPerformanceCounter((LARGE_INTEGER*)&counter_end);
double time=(double)(counter_end-counter_begin)/large;
printf("main Time is %I64d,%lf\n",counter_end-counter_begin,time);

int sign1=GetProcessAffinityMask(GetCurrentProcess(),(LPDWORD)&dwP1,(LPDWORD)&dwS1);
sign1=GetProcessAffinityMask(GetCurrentProcess(),(LPDWORD)&dwP2,(LPDWORD)&dwS2);

QueryPerformanceCounter((LARGE_INTEGER*)&counter_begin); //顺序执行部分
TreadFuc1(NULL);
TreadFuc2(NULL);
QueryPerformanceCounter((LARGE_INTEGER*)&counter_end);
time=(double)(counter_end-counter_begin)/large;
printf("main Time is %I64d,%lf\n",counter_end-counter_begin,time);


printf("main thread exit.\n");
return 0;
}

...全文
1854 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
chxy85 2009-09-02
  • 打赏
  • 举报
回复
我觉得多线程最大的用处是你的程序不会没有响应了
flymoon99 2009-09-02
  • 打赏
  • 举报
回复
多线程的用处在于,做某个耗时的操作时,需要等待返回结果,这时用多线程可以提高程序并发程度。如果一个不需要任何等待并且顺序执行能够完成的任务,用多线程简直是浪费。
jackyjkchen 2009-09-02
  • 打赏
  • 举报
回复
你试一下双核三线程,保准效率反而比双线程低!

算法同样时,CPU占用率达到100%的最小线程数效率最高,如果是cpu占率率高的运算单核单线程,双核双线程,四核四线程是最适合的。

但为什么有时候线程数超过CPU内核数会更快呢?原因是这种程序的单个线程运算量不足以占满CPU一个内核(比如存在大量IO操作,IO比较慢,是程序瓶颈)。
曾经的董胖 2009-09-02
  • 打赏
  • 举报
回复
#3楼说的是对的。所以一般没有必要的话,尤其在单核CPU的时候,不推荐使用多线程。
单核CPU时使用多线程,通常是有线程要处于等待状态。
而对于普通的进度条更新类的,能够简单控制的(比如:在循环里面手动处理消息)就简单控制,一般不使用线程,这样可以提高程序的性能。并且避免掉不必要的线程同步问题。
fantiyu 2009-09-02
  • 打赏
  • 举报
回复
单核CPU上运行的多线程程序, 同一时间只能一个线程在跑, 系统帮你切换线程而已, 系统给每个线程分配时间片来执行, 每个时间片大概10ms左右, 看起来像是同时跑, 但实际上是每个线程跑一点点就换到其它线程继续跑

效率不会有提高的
切换线程反倒会增加开销
dirdirdir3 2009-09-02
  • 打赏
  • 举报
回复
多线程在单cpu中其实也是顺序执行的,不过系统可以帮你切换那个执行而已,其实并没有快(反而慢)
多个cpu的话就可以在两个cpu中同时执行了..............
hhwei1985 2009-09-02
  • 打赏
  • 举报
回复
sf

15,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧