我需要防止处理器进入空闲状态(非C0 C状态)。 不可否认,我对处理器C和P的状态了解不多,所以请耐心等待。 我们使用来自第三方供应商偶尔提供损坏帧的相机。 供应商已经确定,当CPU进入空闲状态时,它会干扰火线上的帧的传输。 为了确认这一点,我在Windows 7 PC上使用了下面的代码,事实上,禁用闲置状态解决了这个问题。
//WIN7 const DWORD DISABLED = 1; const DWORD ENABLED = 0; GUID *scheme; PowerGetActiveScheme(NULL, &scheme); PowerWriteACValueIndex(NULL, scheme, &GUID_PROCESSOR_SETTINGS_SUBGROUP, &GUID_PROCESSOR_IDLE_DISABLE, DISABLED); PowerSetActiveScheme(NULL, scheme);
如果我运行我的应用程序并打开Windows Permon并添加%C1时间,%C2时间和%C3时间,当我禁用这些状态时,我发现它们全部为零,当启用它们时,我看到了相当多的时间C3状态(这是戴尔Precision T3500四核电脑)。
我也需要在XP上执行此操作,但这些调用在XP上不可用。 所以我试图做以下操作来禁用闲置状态
unsigned int ActPwrSch; DWORD currPolicy,newPolicy, curr1Policy,curr2Policy, new1Policy, new2Policy; MACHINE_PROCESSOR_POWER_POLICY Policy; if(GetActivePwrScheme(&ActPwrSch)) { if(ReadProcessorPwrScheme(ActPwrSch,&Policy)) { printf("Read Power Scheme:\n"); //if(Policy.ProcessorPolicyAc.DisableCStates!=0) currPolicy = Policy.ProcessorPolicyAc.Policy[0].AllowPromotion; curr1Policy = Policy.ProcessorPolicyAc.Policy[1].AllowPromotion; curr2Policy = Policy.ProcessorPolicyAc.Policy[2].AllowPromotion; Policy.ProcessorPolicyAc.Policy[0].AllowPromotion = 0; Policy.ProcessorPolicyAc.Policy[1].AllowPromotion = 0; Policy.ProcessorPolicyAc.Policy[2].AllowPromotion = 0; newPolicy = Policy.ProcessorPolicyAc.Policy[0].AllowPromotion; if(WriteProcessorPwrScheme(ActPwrSch,&Policy)) { printf("WriteProcessorPwrScheme succeed\n"); if(SetActivePwrScheme(ActPwrSch,0,0)) { printf("SetActivePwrScheme succeed!!\n"); } } }
但是当我运行我的应用程序时,我仍然可以看到处理器花费在C1状态的时间(通过在perfmon中查看相同的计数器)。 而且我仍然得到我的损坏的图像问题。 XP个人电脑是一个单核戴尔optiplex电脑。
有谁知道我可以如何防止在XP上进入任何C1-C3状态? 正如我所说,似乎我已经在Windows 7上做到了。
您可以使用SetThreadExecutionState函数使应用程序通知系统正在使用它。
编辑:经过一点研究和测试,我来到一个解决方案,或者我想我做了。 你在Windows XP的正确轨道上。 如果你阅读了PROCESSOR_POWER_POLICY结构的文档,你会注意到你可以禁用每个冒犯你的C状态:
Policy[0].AllowPromotion = 0; // Disable's C1 (usually C1 won't cause problems, so you should leave it alone.) Policy[1].AllowPromotion = 0; // Disable's C2 Policy[2].AllowPromotion = 0; // Disable's C3
在Vista和Windows7中,你不能使用这个接口,而是你必须这样做:
GUID *scheme; PowerGetActiveScheme(NULL, &scheme); PowerWriteACValueIndex(NULL, scheme, &GUID_PROCESSOR_SETTINGS_SUBGROUP, &GUID_PROCESSOR_IDLE_DISABLE, 1); PowerSetActiveScheme(NULL, scheme);
我还没有找到一种方法来禁用Vista和Windows 7上的个人C状态。如果你需要一些示例代码,请给我发电子邮件,我可以帮你。
这似乎是为我工作:
void PowerState(bool bEnable) { // CPU idle state unsigned int ActPwrSch; MACHINE_PROCESSOR_POWER_POLICY Policy; if (GetActivePwrScheme(&ActPwrSch)) { if (ReadProcessorPwrScheme(ActPwrSch, &Policy)) { Policy.ProcessorPolicyAc.Policy[0].AllowPromotion = bEnable ? 1: 0; // C1 Policy.ProcessorPolicyAc.Policy[1].AllowPromotion = bEnable ? 1: 0; // C2 Policy.ProcessorPolicyAc.Policy[2].AllowPromotion = bEnable ? 1: 0; // C3 if (WriteProcessorPwrScheme(ActPwrSch, &Policy)) SetActivePwrScheme(ActPwrSch, 0, 0); } } OSVERSIONINFO osvi; memset(&osvi, 0, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osvi); // For Vista and above if (osvi.dwMajorVersion >= 6) { static const GUID processor_idle_disable_guid = {0x5d76a2ca, 0xe8c0, 0x402f, 0xa1, 0x33, 0x21, 0x58, 0x49, 0x2d, 0x58, 0xad}; GUID *scheme; PowerGetActiveScheme(NULL, &scheme); PowerWriteACValueIndex(NULL, scheme, &GUID_PROCESSOR_SETTINGS_SUBGROUP, &processor_idle_disable_guid, bEnable ? 0 : 1); PowerSetActiveScheme(NULL, scheme); } }
当然,每5分钟运行一次数学计算的TSR将防止空闲状态? 或者,您可以购买一个便宜的硬件或软件鼠标仿真器,以定义的时间间隔发送鼠标移动信号。