最近玩细胞分裂6,发现机器配置应该不算太差,但是游戏玩起来一卡一卡的,很不爽,我记得好象之前下过5的时候就是这样卡,然后玩了没两下就删掉了。。。
这次从网上查了查,发现是CPU的相关性设置出了问题。我的笔记本是i5的cpu,是双核四线程,但是游戏默认只会使用每个核心的一个线程一共两个线程,把所有CPU都勾上就会很流畅了。
但是还有一个麻烦的就是貌似游戏每次切换关卡后,游戏还会重新的把相关性设置一遍。。。这样下一关就又卡了,还得切出来重新设置。
这样玩的很不爽,于是就从网上搜了一下.NET关于设置进程CPU相关性的内容,看起来很简单,设置Process的ProcessAffinity属性就可以了。然后设置了一个Timer让它一秒钟检查一次CPU相关性有没有被修改,如果被修改了就再改回去。。。
大概就是这样吧,上两篇随便也是因为这件事情写出来的。。。
简单说一下主要部分:
// 根据关键词获取系统中的进程 var processes = from p in Process.GetProcesses() where p.ProcessName.ToLower().Contains(key.ToLower()) select p;
通过查找ProcessName来大概找到要设置的进程
然后列出列表后让用户选择,用户选择后根据Id读取该进程的CPU相关性:
// 获取进程信息 Process process = Process.GetProcessById(id); int cpu = process.ProcessorAffinity.ToInt32();
这里要注意的是,CPU的相关性是以掩码形式存储在IntPtr中,所以我的4个逻辑处理器如果全部勾选,读取出来的就是15,其实就是二进制的1111。需要做一个简单的判断来确定是否与某CPU关联:
/// <summary> /// 通过相关性编码获取某CPU的相关性设置 /// </summary> /// <param name="affinity">进程的相关性编码</param> /// <param name="cpu">要获取的cpu编号,从0计</param> /// <returns></returns> public bool GetCPUAffinity(int affinity, int cpu) { return (affinity >> cpu | 15) == 15; }
然后设置到界面相应的复选框中:
cb_cpu0.Checked = GetCPUAffinity(cpu, 0); cb_cpu1.Checked = GetCPUAffinity(cpu, 1); cb_cpu2.Checked = GetCPUAffinity(cpu, 2); cb_cpu3.Checked = GetCPUAffinity(cpu, 3);
读取用户选择的时候:
/// <summary> /// 获取当前界面CPU相关性的选项 /// </summary> /// <returns></returns> public int GetSetCPU() { int cpu = 0; if (cb_cpu0.Checked) { cpu |= 1; } if (cb_cpu1.Checked) { cpu |= 2; } if (cb_cpu2.Checked) { cpu |= 4; } if (cb_cpu3.Checked) { cpu |= 8; } return cpu; }
写的比较死了,有时间再考虑怎么支持任意数量。
再把用户的选择设回进程的相关性就可以了,这里简单做了一个判断,如果读取到进程的CPU相关性和要设置的相等,就不再设置了,虽然不知道这样做会不会让系统少点负担。。。
process = Process.GetProcessById(id); if (process.ProcessorAffinity.ToInt32() != cpu) { process.ProcessorAffinity = (IntPtr)cpu; }
大概就是这样吧。目前只支持4个逻辑处理器的系统使用。
项目下载:http://pan.baidu.com/share/link?shareid=2976071931&uk=989945664
程序下载:http://pan.baidu.com/share/link?shareid=2977186279&uk=989945664