高分求教:四核多线程,为什么CPU占用最多只有25%

FrozenSea 2013-11-04 09:36:07
VS2005, C++开发,四核i7笔记本, WinXP SP3

程序一共3个线程:用户UI、消息接收和数据计算。在数据计算线程明显满负荷已经不能实时处理(显示延迟很明显)时,CPU占用率依然不超过25%。此时消息接收线程也有相当的处理负荷,如能多核应该超过25%才对。

消息接收和数据计算线程使用了信号量进行了同步,但用的很少且处理时间很短。

问题如下:
1. 单进程下的程序是否再多的线程也只能用一个CPU?如果能使用多核的话,该如何设置?
2. 信号量同步是否对CPU使用有影响?

欢迎答复,有答必给分。多谢了。


...全文
1326 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
q_sdfg123 2013-12-05
  • 打赏
  • 举报
回复
看了上面的回复吐血了 单进程程序,不管开多少线程,只能占用一个CPU,这还需要讨论? 单纯的数据计算使用多线程没有多大益处,线程切换同步会浪费CPU资源 多线程只适合线程阻塞或者多任务
FrozenSea 2013-11-11
  • 打赏
  • 举报
回复
上周实验完毕,做了一下测试 结论: 1. 多核系统中,单进程下的程序使用多线程即可增加CPU占用率。无须额外设置 2. 线程同步会一定程度的影响CPU负荷。代码中若每10次同步一次,那么双线程差不多是50%,若每5次同步一次则降到30多 谢谢各位参与,散分结贴。附测试代码,供参考 ============================================================= #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <time.h> #include <windows.h> #include <process.h> typedef enum{ MAT_TASK1, MAT_TASK2 } EMatTask; const int BUF_SIZE = 1024; bool bTask1 = 0; bool bTask2 = 0; int g_nCount = 0; CRITICAL_SECTION g_cs; double func(double N) { int k; int count = 0; double x, y; srand( (unsigned)time( NULL ) ); for(k = 1; k <= (int) N; k++) { x = 2.0 * rand() / RAND_MAX - 1; y = 2.0 * rand() / RAND_MAX - 1; if(sqrt(x * x + y * y) <= 1) count++; // Test how CriticalSection effects the computation efficiency // Set it to (k % 5) or (k % 10) to see difference if( (k % 5) == 0 ) // 每5次运算同步一次 { EnterCriticalSection( &g_cs ); g_nCount++; LeaveCriticalSection( &g_cs ); } } return (4.0 * count / N); } void MatTask(void *pTaskID) { const double IterNum1 = 5e7; const double IterNum2 = 10e7; double T; double y; EMatTask TaskID; TaskID = *((EMatTask *)pTaskID); if(TaskID == MAT_TASK1) { T = IterNum1; y = func(T); printf("Task1: IterNum = %.0f, Result = %f\n", T, y); bTask1 = 1; } else if(TaskID == MAT_TASK2) { T = IterNum2; y = func(T); printf("Task2: IterNum = %.0f, Result = %f\n", T, y); bTask2 = 1; } printf(" g_nCount = %d \n", g_nCount); } void main() { static EMatTask TaskID1, TaskID2; bool bThreadMode = 1; TaskID1 = MAT_TASK1; TaskID2 = MAT_TASK2; InitializeCriticalSection( &g_cs ); if(!bThreadMode) { MatTask((void *)&TaskID1); MatTask((void *)&TaskID2); } else { _beginthread( MatTask, 0, (void *)&TaskID1 ); _beginthread( MatTask, 0, (void *)&TaskID2 ); while(!(bTask1 & bTask2)) { Sleep(100); } } DeleteCriticalSection( &g_cs ); }
FrozenSea 2013-11-05
  • 打赏
  • 举报
回复
非常感谢诸位的回答 先解释一下各部分的运算量: 1)消息接收线程负责解码接收到的消息,并使用信号量放入公用缓存 2)数据计算线程是定期把公用缓存中的消息读入另一个计算缓存并显示,并没有实质意义上的计算。 我有测试用例可以发送海量消息,此时数据计算线程满负荷达25%,其他线程哪怕只有1%,显示CPU占用26%我觉得也可以理解,但现在就是没有超过25%。 此外我比较倾向于caozhy的分析,可能是信号量和网络等其他地方阻碍了运行效率。这两天写点程序试试,而后再来回报。
threenewbee 2013-11-04
  • 打赏
  • 举报
回复
25%说明只有一个线程被调度。 应该是你过分加锁所致。或者你的负载不在CPU而在网络、IO或者其它地方。
rtdb 2013-11-04
  • 打赏
  • 举报
回复
呵呵,其实一楼已回答了。 你的3个线程,只有数据计算线程可能达到100%, 其他的线程,例如“消息接收线程”,不出意外的话,一般也就1%。 所以在4核中,你只能用满1核,25%。 总之,要想提高CPU利用, 你要想办法把数据计算分成多线程处理。
FrozenSea 2013-11-04
  • 打赏
  • 举报
回复
现在讨论的就是为什么开了多线程,却没有起到多核分担的效果。我的问题很明确,就是上面说的两点。 感谢参与,虽然答非所问。程序各部分的运算量如何,我也是老程序员,心里很清楚。
  • 打赏
  • 举报
回复
引用 楼主 FrozenSea 的回复:
此时消息接收线程也有相当的处理负荷,如能多核应该超过25%才对
消息接收线程再“有相当的处理负荷”,跟你的所谓“数据计算线程”相比也是九牛一毛。 你得数据计算应该多线程处理。这就好比如说核心路线不优化,净把时间浪费在根本就很松弛的路线上,有什么意义呢?

7,540

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 VC.NET
社区管理员
  • VC.NET社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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