c ++ - Forsøger at deaktivere processor inaktive tilstande (C-stater) på Windows PC

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg skal forhindre processoren i at gå i tomgangstilstand (ikke C0 C-tilstand). Ganske vist ved jeg ikke meget om processor C og P-stater, så bære med mig.
Vi bruger et kamera fra en tredjepartsleverandør, der lejlighedsvis leverer beskadigede rammer. Sælgeren har fastslået, at når CPU'en går i tomgang, påvirker den overførslen af ​​rammen over firewire.
For at bekræfte dette anvendte jeg følgende kode på en Windows 7-pc, og i virkeligheden blev deaktiveret deaktiverede stater løst problemet.


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


Hvis jeg kører min ansøgning og åbner Windows permon og tilføjer\% C1 Time,\% C2 Time og\% C3 tid ser jeg, at de er alle nul, når jeg deaktiverer disse stater, når jeg aktiverer dem, ser jeg lidt tid i C3-tilstand (dette er på en Dell Precision T3500 quad core-pc).


Jeg skal også gøre dette på XP, men disse opkald er ikke tilgængelige på XP. Så jeg forsøgte at gøre følgende for at deaktivere tomgangsstaterne


  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:
"); 
        //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
"); 
            if(SetActivePwrScheme(ActPwrSch,0,0)) 
            { 
                printf("SetActivePwrScheme succeed!!
");
            } 
        }

    } 


Men når jeg kører min ansøgning ser jeg stadig, at processoren bruger tid i C1-staten (ved at se på de samme tællere i perfmon). Og jeg får stadig mit ødelagte billedproblem. XP-pc'en er en single core Dell optiplex PC.


Er der nogen, der ved, hvordan jeg kan forhindre adgang til nogen af ​​C1-C3-staterne på XP? Som jeg sagde, synes det at jeg har gjort det på Windows 7.

Bedste reference


Du kan bruge SetThreadExecutionState-funktionen, som gør det muligt for applikationen at oplyse det system, det er i brug.


EDIT: Efter lidt forskning og test kom jeg til en løsning, eller jeg tror jeg gjorde det. Du er på rette spor til Windows XP. Hvis du læser dokumentationen til PROCESSOR\_POWER\_POLICY strukturen, vil du bemærke, at du kan deaktivere hver C-stat, der fornærmer dig:


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






I Vista og Windows7 kan du ikke bruge denne grænseflade i stedet for at gøre dette:


GUID *scheme;
PowerGetActiveScheme(NULL, &scheme); 
PowerWriteACValueIndex(NULL, scheme, &GUID\_PROCESSOR\_SETTINGS\_SUBGROUP,  &GUID\_PROCESSOR\_IDLE\_DISABLE, 1); 
PowerSetActiveScheme(NULL, scheme);






Jeg har ikke fundet en måde at deaktivere individuelle C-stater på Vista og Windows 7. Hvis du har brug for nogle prøvekoder, kan du kontakte mig, så jeg kan hjælpe dig.

Andre referencer 1


Dette ser ud til at virke for mig:


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

Andre referencer 2


Sikkert en TSR, der kører en matematisk beregning hvert 5. minut, forhindrer en inaktiv tilstand?
Alternativt kan du købe en billig hardware eller software musemulator, der sender et musebevægelsessignal med definerede intervaller.