Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to disable Processor idle states (C states) on Windows PC

I need to prevent the processor from entering an idle state (non C0 C state). Admittedly I do not know much about processor C and P states so bear with me. We use a camera from a third party vendor which occasionally delivers corrupted frames. The vendor has determined that when the CPU enters an idle state it interferes with the transmission of the frame over the firewire. To confirm this I used the following code on a Windows 7 PC and indeed, disabling the idle states resolved the issue.

   //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);

If I run my application and open Windows permon and add the %C1 Time, %C2 Time and %C3 time I see that they are all zero when I disable these states, when I enable them I see quite a bit of time spent in the C3 state (this is on a Dell Precision T3500 quad core PC).

I also need to do this on XP however these calls are not available on XP. So I attempted to do the following to disable the idle states

  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");
            } 
        }

    } 

However when I run my application I still see that the processor is spending time in the C1 state (by looking at the same counters in perfmon). And I still get my corrupted image problem. The XP PC is an single core Dell optiplex PC.

Does anybody know how I can prevent entry into any of the C1-C3 states on XP? As I said it seems that I have done it on Windows 7.

like image 790
mash Avatar asked Mar 15 '12 13:03

mash


People also ask

How do I disable CPU C States?

From the System Utilities screen, select System Configuration > BIOS/Platform Configuration (RBSU) > Power and Performance Options > C-State Efficiency Mode. Select one of the following: Enable. Disable.

How do I stop my CPU from idling?

In Windows' Power Settings, change the advanced settings of your plan, find Processor power management -> Processor idle disable, and set it to Disable Idle.

Does disabling C states increase performance?

Note: Changing the C state in the BIOS settings does not affect performance of the device however it will take more time for the CPU to fully "wake up" from sleep mode.

What is C states in BIOS?

These modes or "C-states" start at C0, which is the normal CPU operating mode (the CPU is 100% activated). The higher the C number is, the deeper into sleep mode the CPU goes. In other words, more circuits and signals are turned off, and the CPU takes more time to fully wake up into C0 mode.


1 Answers

You can use SetThreadExecutionState function which enables the application to inform the system that it is in use.

EDIT: After a little research and testing I came to a solution or I think I did. You're on the right track for Windows XP. If you read the documentation for the PROCESSOR_POWER_POLICY structure , you'll notice you can disable each C-states that offends you:

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


In Vista and Windows7 you can't use this interface instead you have to do this:

GUID *scheme;
PowerGetActiveScheme(NULL, &scheme); 
PowerWriteACValueIndex(NULL, scheme, &GUID_PROCESSOR_SETTINGS_SUBGROUP,  &GUID_PROCESSOR_IDLE_DISABLE, 1); 
PowerSetActiveScheme(NULL, scheme);


I haven't found a way to disable individual C states on Vista and Windows 7. If you need some sample codes please email me I can help you out.

like image 139
Dylan Cole Avatar answered Nov 14 '22 15:11

Dylan Cole