如何让程序运行在所有CPU核心上
先解释几个概念:多CPU,多核,超线程
多CPU:(一台主机的)主板上有多个CPU。
多核:一个CPU有多个核心(下图是6个物理核心)。
超线程:CPU有一个重要的参数是某个型号的CPU是否支持超线程。例如,某个CPU有4个物理核心,它支持超线程技术,那么在逻辑上可以看作8个核心(也叫4核8线程)。比如我们在中关村在线上看到某款CPU的参数如下:
表明这款CPU是支持超线程技术的。
在Windows系统下如何设置一个进程能在所有的(逻辑)核心上执行呢?
方法一:在任务管理器中设置进程的相关性。
方法二:在C#中Environment.ProcessorCount可以得到当前CPU的所有逻辑核心。
1 static void SetProcessorAffinity() 2 { 3 pfcLogger logger = new pfcLogger(); 4 5 try 6 { 7 Process proc = Process.GetCurrentProcess(); 8 long affinitymask = (long)proc.ProcessorAffinity; 9 10 switch (Environment.ProcessorCount) 11 { 12 //Environment.ProcessorCount includes any hyperthreaded processors 13 14 case 2: affinitymask = 0x0003; break; // number of logical processors: 2 15 case 4: affinitymask = 0x000F; break; // number of logical processors: 4 16 case 8: affinitymask = 0x00FF; break; // number of logical processors: 8 17 case 12: affinitymask = 0x0FFF; break; // number of logical processors: 12 18 case 16: affinitymask = 0xFFFF; break; // number of logical processors: 16 19 default: break; // keep its default processorAffinity 20 } 21 proc.ProcessorAffinity = (IntPtr)affinitymask; 22 } 23 catch (System.ComponentModel.Win32Exception cwe) 24 { 25 MessageBox.Show("Fail to set processor affinity attribute. " + cwe.Message); 26 logger.Error(DateTime.Now, null, "PackOne.Server.Startup.Program", MethodBase.GetCurrentMethod().Name, cwe); 27 } 28 catch (System.NotSupportedException nse) 29 { 30 MessageBox.Show("Fail to set processor affinity attribute. " + nse.Message); 31 logger.Error(DateTime.Now, null, "PackOne.Server.Startup.Program", MethodBase.GetCurrentMethod().Name, nse); 32 } 33 catch (System.InvalidOperationException ioe) 34 { 35 MessageBox.Show("Fail to set processor affinity attribute. " + ioe.Message); 36 logger.Error(DateTime.Now, null, "PackOne.Server.Startup.Program", MethodBase.GetCurrentMethod().Name, ioe); 37 } 38 catch (Exception e) 39 { 40 MessageBox.Show("Fail to set processor affinity attribute. " + e.Message); 41 logger.Error(DateTime.Now, null, "PackOne.Server.Startup.Program", MethodBase.GetCurrentMethod().Name, e); 42 } 43 }
说明:上面的代码的关键部分是这样:
Process proc = Process.GetCurrentProcess(); long affinitymask = (long)proc.ProcessorAffinity; switch (Environment.ProcessorCount) { //Environment.ProcessorCount includes any hyperthreaded processors case 2: affinitymask = 0x0003; break; // number of logical processors: 2 case 4: affinitymask = 0x000F; break; // number of logical processors: 4 case 8: affinitymask = 0x00FF; break; // number of logical processors: 8 case 12: affinitymask = 0x0FFF; break; // number of logical processors: 12 case 16: affinitymask = 0xFFFF; break; // number of logical processors: 16 default: break; // keep its default processorAffinity } proc.ProcessorAffinity = (IntPtr)affinitymask;
其他代码是用于写日志和异常处理的。
另外,如何在windows上查看某个CPU的物理核心和逻辑核心呢?
使用命令:WMIC CPU Get DeviceID,NumberOfCores,NumberOfLogicalProcessors
如果NumberOfCores = NumberOfLogicalProcessors ,则表明该CPU不支持超线程。