如何通过多线程利用多CPU运算?(200分)

  • 主题发起人 凝铁衣
  • 开始时间

凝铁衣

Unregistered / Unconfirmed
GUEST, unregistred user!
我有一个超大运算量的运行过程,服务器是4CPU,每个CPU4核的,我设置了15个线程,结果发现只有4个核在运行,是不是这四个核都属于一个CPU,其他CPU全都闲置着?
如何才能够充分利用服务器的CPU呢?
望高手解答,或提供一些思路,万分感谢!!在线等...
 
操作系统有API可以设置亲缘性
 
“hard affiinty”(硬亲缘性),使用它可以控制哪个CPU运行哪些线程。
SetProcessAffinityMask函数限制一个特定的进程只能运行在CPU的一个子集上。

BOOL SetProcessAffinityMask(
HANDLE hProcess,
DWORD_PTR dwProcessAffinityMask);

  该函数得第一个参数指明了要被限制的进程,第二个参数是一个“位屏蔽”数据,里面的每个位表示一个CPU代号(从0开始标号),比如0x00000001表示选中CPU 0,也就是“该进程中的线程”只能运行在CPU 0上了;0x00000005表示同时选中CPU 0和CPU 2。
  一个进程中的子进程可以继承该进程的亲缘性,也可以使用作业内核对象对某些进程限制在要求的一组CPU上执行。

  可以调用GetProcessAffinityMask函数来取得一个进程亲缘性屏蔽信息。

BOOL GetProcessAffinityMask(
HANDLE hProcess,
PDWORD_PTR pdwProcessAffinityMask,
PDWORD_PTR pdwSystemAffinityMask);

  该函数通过第二个参数返回指定进程的CPU的亲缘性信息,同时可以通过第三个参数返回系统亲缘性信息。系统亲缘性指明系统的哪些CPU可以处理线程,进程的亲缘性始终是系统亲缘性的子集。

  以上讨论的是如何把一个进程中的所有线程限制在一组CPU上。有的时候想要把进程的一个具体线程限制在一组CPU上。
  SetThreadAffinityMask函数可以限制某一个线程只能运行在一组CPU上。
DWORD_PTR SetThreadAffinityMask(
HANDLE hThread,
DWORD_PTR dwThreadAffinityMask);

  该函数的第二个参数的意义和SetProcessAffinityMask函数中的第二个参数相同。也必须指明了一个正确的CPU子集,限制指定的线程只能运行在这个CPU子集上。该函数返回原来的线程的亲缘信息。
  比如,现在有4个线程和4个可用的CPU,你想让线程1独占CPU 0,让其他3个线程只能运行在CPU 1、CPU 2、CPU 3上,可以如下编码:
SetThreadAffinityMask(hThread0, 0x00000001);
SetThreadAffinityMask(hThread1, 0x0000000E);
SetThreadAffinityMask(hThread2, 0x0000000E);
SetThreadAffinityMask(hThread3, 0x0000000E);
 
收到,多谢,我测试一下。
 
那么如何判断CPU的个数呢?
 
SetThreadIdealProcessor可以设置线程工作的CPU.
 
如果你的线程间存在通信
那么将之放到多个cpu上运行会有信号量锁的问题
而处理信号量锁是非常耗费资源的
从这个意义上说 存在线程间通信的多线程并不能完整的发挥多cpu的运算能力
如果你的线程间没有通信 那么就没有必要做成多线程
msn ball_cao@hotmail.com
 
经过测试发现,使用多线程的时候操作系统会自动将多线程调度到多CPU的多核上运行,如果线程间没有同步操作的话(如建几个死循环的线程),但是一旦线程中存在同步,则导致无法完全利用多CPU的性能,正象ball_cao所说的那样。所以目前我已经修改了算法,尽量减少了线程间的通信,现在的程序已经提高了10倍的性能!
 
高手。恭喜你,但我对你们说的一点都不明白。还要多向 你们学习啊。
 
顶部