2012-03-15 1 views
7

Je dois empêcher le processeur d'entrer dans un état inactif (état autre que C0 C). Certes, je ne connais pas grand-chose à propos des états C et P du processeur, alors gardez-moi. Nous utilisons une caméra d'un fournisseur tiers qui fournit occasionnellement des trames corrompues. Le fournisseur a déterminé que lorsque la CPU entre dans un état inactif, elle interfère avec la transmission de la trame sur le firewire. Pour confirmer cela, j'ai utilisé le code suivant sur un PC Windows 7 et en effet, la désactivation des états inactifs a résolu le problème.Tentative de désactivation des états d'inactivité du processeur (états C) sous Windows 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); 

Si je lance mon application et ouvrez Windows Permon et ajouter% Temps C1,% C2 Temps et% du temps C3 Je vois qu'ils sont tous nuls quand je désactiver ces états, quand je leur permettre, je vois tout à fait un peu de temps passé à l'état C3 (c'est sur un PC quadricœur Dell Precision T3500).

J'ai également besoin de faire cela sur XP mais ces appels ne sont pas disponibles sur XP. Donc, je tentais de faire ce qui suit pour désactiver les états de repos

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

    } 

Cependant quand je lance mon application, je vois encore que le processeur est de passer du temps dans l'état C1 (en regardant les mêmes compteurs dans perfmon). Et j'ai toujours mon problème d'image corrompue. Le PC XP est un PC optiplex Dell à cœur unique.

Est-ce que quelqu'un sait comment je peux empêcher l'entrée dans l'un des états C1-C3 sous XP? Comme je l'ai dit, il semble que je l'ai fait sur Windows 7.

+3

Wow, cela semble douloureux. Je suppose que convaincre le vendeur de livrer un pilote qui fonctionne * est hors de question? – jalf

+0

Vous ne savez pas si cela est tout à fait pertinent, mais ne pas définir 'Policy.ProcessorPolicyAc.DynamicThrottle' sur' PO_THROTTLE_NONE' peut-être aider? – Hasturkun

+0

Ha ... il semble que ce soit pour le moment jalf. Nous travaillons à changer de fournisseur mais pour l'instant je suis coincé. Douloureux en effet. – mash

Répondre

2

Vous pouvez utiliser la fonction SetThreadExecutionState qui permet à l'application d'informer le système qu'elle est en cours d'utilisation.

EDIT: Après un peu de recherche et de tests, je suis arrivé à une solution ou je pense que je l'ai fait. Vous êtes sur la bonne voie pour Windows XP. Si vous lisez la documentation de la structure PROCESSOR_POWER_POLICY, vous remarquerez que vous pouvez désactiver chaque C-états que vous offense:

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 


Dans Vista et Windows7 vous ne pouvez pas utiliser cette interface plutôt que vous doivent faire:

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


Je ne l'ai pas trouvé un moyen de désactiver individuellement les États C o n Vista et Windows 7. Si vous avez besoin de quelques exemples de codes s'il vous plaît écrivez-moi, je peux vous aider.

+0

J'ai essayé cela, je pense que cela va empêcher le PC de se mettre en veille, mais n'a pas d'effet sur les états C des processeurs individuels? Je ne suis pas sûr ... mais mon CPU est encore entré dans l'état C1. Merci – mash

+0

Mis à jour. Dites-moi comment ça fonctionne. –

+0

Hey Dylan, j'ai effectivement ce même code dans le message original. Pour une raison quelconque, le code XP ne semble pas fonctionner. Je vois toujours mon CPU entrer dans l'état C1. Sur Win7 je ne vois pas le CPU entrer dans l'état C1. – mash

2

Cela semble fonctionner pour moi:

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

Merci d'avoir essayé ça. Quand je l'exécute, je vois que la CPU n'entrera pas dans C2 ou dans l'état C3 mais elle entrera dans l'état C1. J'ai essayé cela sur plusieurs systèmes XP (simple et multi core) et j'obtiens les mêmes résultats. Il semble que je ne peux pas empêcher le système d'entrer tous les états C sur XP. Sur Win7, il semble que je peux. – mash

+0

Je vous ai envoyé un e-mail. Il semble que tous les états C ne puissent pas être désactivés sur XP comme ils le peuvent sur Windows 7. J'ai essayé de jouer avec les paramètres AllowDemotion aussi, mais cela semble n'avoir aucun effet. – mash

2

Sûrement un TSR en cours d'exécution d'un calcul mathématique toutes les 5 minutes empêcheront un état de repos? Vous pouvez également acheter un émulateur de souris matériel ou logiciel bon marché qui envoie un signal de déplacement de la souris à des intervalles définis.

+1

Ce genre de chose pourrait empêcher l'ordinateur de se mettre en veille, mais cela n'empêchera pas l'ordinateur de décider qu'il n'a pas besoin de faire fonctionner les quatre cœurs du processeur et de mettre un ou plusieurs d'entre eux en veille. –