2012-03-15 15 views
7

Necesito evitar que el procesador entre en un estado inactivo (estado no C0 C). Es cierto que no sé mucho acerca de los estados del procesador C y P, así que tengan paciencia conmigo. Utilizamos una cámara de un proveedor externo que ocasionalmente entrega marcos dañados. El vendedor ha determinado que cuando la CPU entra en estado inactivo interfiere con la transmisión del cuadro sobre el cable firewire. Para confirmar esto, utilicé el siguiente código en una PC con Windows 7 y, de hecho, deshabilitar los estados inactivos resolvió el problema.Intentando deshabilitar estados inactivos del procesador (estados C) en PC con Windows

//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 funciono mi solicitud y abra Windows Permon y añadir el% C1 Tiempo,% Tiempo C2 y hora% C3 veo que todos son cero cuando desactivo estos estados, cuando yo les permitan veo bastante un poco de tiempo en el estado C3 (esto es en una PC Dell Precision T3500 de cuatro núcleos).

También necesito hacer esto en XP pero estas llamadas no están disponibles en XP. Así que he tratado de hacer lo siguiente para desactivar los estados de inactividad

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

    } 

Sin embargo, cuando ejecuto mi aplicación Todavía veo que el procesador está gastando tiempo en el estado C1 (mirando a los mismos contadores en Monitor de rendimiento). Y todavía tengo mi problema de imagen corrupto. La PC XP es una PC Dell Optiplex de un solo núcleo.

¿Alguien sabe cómo puedo evitar la entrada en cualquiera de los estados C1-C3 en XP? Como dije, parece que lo he hecho en Windows 7.

+3

Guau, eso suena doloroso. Supongo que conseguir que el proveedor solo entregue un controlador que * funciona * está fuera de discusión. – jalf

+0

No estoy seguro de si esto es del todo relevante, pero ¿no sería posible establecer 'Policy.ProcessorPolicyAc.DynamicThrottle' en' PO_THROTTLE_NONE' posiblemente? – Hasturkun

+0

Ha ... parece ser por ahora jalf. Estamos trabajando para cambiar de proveedor, pero por ahora estoy atascado. Doloroso de hecho. – mash

Respuesta

2

Puede usar la función SetThreadExecutionState que permite a la aplicación informar al sistema que está en uso.

EDIT: Después de un poco de investigación y pruebas llegué a una solución o creo que lo hice. Estás en el camino correcto para Windows XP. Si usted lee la documentación de la estructura PROCESSOR_POWER_POLICY, se dará cuenta que puede desactivar cada uno C-estados que le ofende:

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 


En Vista y Windows 7 no puede utilizar esta interfaz en lugar de eso han de hacer esto:

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


no he encontrado una manera de desactivar individuo o C Unidos n Vista y Windows 7. Si necesita algunos códigos de muestra, envíeme un correo electrónico para ayudarlo.

+0

Intenté esto, creo que esto evitará que la PC se quede dormida pero no tenga un efecto en los estados C de las CPU individuales. No estoy seguro ... pero mi CPU aún entró en el estado C1. Gracias – mash

+0

Actualizado. Déjame saber cómo funciona. –

+0

Hola Dylan, de hecho tengo el mismo código en la publicación original. Por alguna razón, el código XP no parece estar funcionando. Todavía veo que mi CPU ingresa al estado C1. En Win7 no veo que la CPU entre en el estado C1. – mash

2

Esto parece estar funcionando para mí:

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

Gracias por probar esto. Cuando lo ejecuto veo que la CPU no entrará en C2 o en el estado C3, sino que entrará en el estado C1. Intenté esto en múltiples sistemas XP (núcleo único y núcleo múltiple) y obtuve los mismos resultados. Parece que no puedo evitar que el sistema ingrese todos los estados C en XP. En Win7 parece que puedo. – mash

+0

Te he enviado un correo electrónico. Parece como si todos los estados C no se pueden desactivar en XP como lo hacen en Windows 7. He intentado jugar con la configuración de AllowDemotion también, pero parece que no tiene ningún efecto. – mash

2

Sin duda, un TSR ejecución de un cálculo matemático cada 5 minutos para evitar que cualquier estado de reposo? Como alternativa, puede comprar un emulador de mouse barato de hardware o software que envía una señal de movimiento del mouse a intervalos definidos.

+1

Este tipo de cosas podría garantizar que la computadora no se quede dormida, pero no evitará que la computadora decida que no necesita que se ejecuten los cuatro núcleos de la CPU y que uno o más de ellos se duermen. –

Cuestiones relacionadas