Rocho.J

人脑是不可靠的, 随时记录感悟并且经常重复!

 

[转]强制线程或进程在指定的cpu上执行 ----- http://blog.csdn.net/watkinsong/article/details/6871235

通过C#还可以指定当前线程的运行在哪个CPU上。

 

通过

System.Diagnostics.Process p = Process.GetCurrentProcess(); 
            p.ProcessorAffinity = (IntPtr)0x0001; 

Process.ProcessorAffinity 设置当前CPU的屏蔽字,0x0001表示选用一号CPU,0x0002表示选用2号CPU。

 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Diagnostics; 
 
namespace cpu_4_2_csharp 

    class Program 
    { 
        static void Main(string[] args) 
        { 
            System.Diagnostics.Process p = Process.GetCurrentProcess(); 
            p.ProcessorAffinity = (IntPtr)0x0001; 
 
            const int SAMPLING_COUNT = 200; 
            const double PI = 3.14159; 
            const int TOTAL_AMPLITUDE = 250; // the length of each time piece 
            //const int system_busy = 10; // take the system cpu consume into consideration 
 
            double[] busySpan=new double[SAMPLING_COUNT]; 
            int amplitude = (TOTAL_AMPLITUDE) / 2; 
            double radian = 0.0; 
            double radianIncreament = 2.0 / (double)SAMPLING_COUNT; 
 
            for (int i = 0; i < SAMPLING_COUNT; i++) 
            { 
                busySpan[i] = (double)(amplitude + Math.Sin(PI * radian) * amplitude); 
                radian += radianIncreament; 
            } 
 
            int startTick = Environment.TickCount; 
 
            for (int j = 0; ; j = (j + 1) % SAMPLING_COUNT) 
            { 
                startTick = Environment.TickCount; 
                while ((Environment.TickCount - startTick) < busySpan[j]) 
                { 
                    // 
                } 
                System.Threading.Thread.Sleep(TOTAL_AMPLITUDE - (int)busySpan[j]); 
            } 
        } 
    } 

 

 

 

================================

 

 

 

实现方法

进程与指定cpu绑定:SetProcessAffinityMask(GetCurrentProcess(), dwMask);

线程与指定cpu绑定:SetThreadAffinityMask(GetCurrentThread(),dwMask);

dwMask为CPU序号的或运算值:1(0001)代表只运行在CPU12(0010)代表只运行在CPU2,3(0011)代表可以运行在CPU1和CPU2,以此类推。

设置之前最好判断一下系统有几个CPU:

SYSTEM_INFO SystemInfo;

GetSystemInfo(&SystemInfo);

CPU个数:SystemInfo.dwNumberOfProcessors

当前启用的CPU序号:SystemInfo.dwActiveProcessorMask,Mask representing the set of processors configured into the system. Bit 0 is processor 0; bit 31 is processor 31.

CPU亲缘性介绍

按照默认设置,当系统将线程分配给处理器时,Windows使用软亲缘性来进行操作。这意味着如果所有其他因素相同的话,它将设法在它上次运行的那个处理器上运行线程。让线程留在单个处理器上,有助于重复使用仍然在处理器的内存高速缓存中的数据。

有一种新的计算机结构,称为NUMA(非统一内存访问),在该结构中,计算机包含若干块插件板,每个插 件板上有4个CPU和它自己的内存区。
当CPU访问的内存是它自己的插件板上的内存时,NUMA系统运行的性能最好。如果CPU需要访问位于另一个插件板上的内 存时,就会产生巨大的性能降低。在这样的环境中,就需要限制来自一个进程中的线程在共享同一个插件版的CPU上运行。为了适应这种计算机结构的需要,Windows允许你设置进程和线程的亲缘性。换句话说,你可以控制哪个CPU能够运行某些线程。这称为硬亲缘性。请注意,子进程可以继承进程的亲缘性。

注意:

(1)无论计算机中实际拥有多少个CPU,Windows98及以前系统只使用一个CPU,上述API不被支持。

(2)在大多数环境中,改变线程的亲缘性就会影响调度程序有效地在 各个CPU之间移植线程的能力,而这种能力可以最有效地使用CPU时间。

应用场景举例:

将UI线程限制在一个CPU,将其他实时性要求较高的线程限制在另一个CPU。这样,当UI需要占用大量CPU时间时,就不会拖累其他实时性要求较高的线程的执行。同样可以将UI线程与一些优先级不高但耗时的异步运算线程设置在不同CPU上,避免UI给人卡顿的感觉。

 

posted on 2013-10-25 09:08  RJ  阅读(2642)  评论(0)    收藏  举报

导航