2012-09-01 16 views
6

Si uso la siguiente llamada en C++, esperaría que el WorkingSet del proceso nunca caiga por debajo de 100MB.¿Hay alguna manera de forzar el WorkingSet de un proceso de 1 GB en C++?

Sin embargo, el sistema operativo aún recorta el conjunto de trabajo a 16 MB, incluso si realizo esta llamada.

Establecer WorkingSet a 100MB daría lugar a un aumento drástico en la velocidad de mi aplicación, eliminando las fallas de página suave (consulte el diagrama a continuación).

¿Qué estoy haciendo mal?

SIZE_T workingSetSizeMB = 100; 
int errorCode = SetProcessWorkingSetSizeEx(
    GetCurrentProcess(), 
    (workingSetSizeMB - 1) * 1024 * 1024), // dwMinimumWorkingSetSize 
    workingSetSizeMB * 1024 * 1024, // dwMaximumWorkingSetSize, 
    QUOTA_LIMITS_HARDWS_MIN_ENABLE | QUOTA_LIMITS_HARDWS_MAX_DISABLE 
); 
// errorCode returns 1, so the call worked. 

(extra para expertos)metodología experimental

escribí un ensayo C++ proyecto para asignar 100 MB de datos para llevar el WorkingSet más de 100 MB (como se ve en el Explorador de Proceso), a continuación, cancela la asignación que memoria. Sin embargo, el SO recortó el WorkingSet a 16 MB tan pronto como desasigné esa memoria. Puedo proporcionar el proyecto C++ de prueba que utilicé si lo desea.

¿Por qué Windows proporciona una llamada a SetProcessWorkingSetSizeEx() si no parece funcionar? Debo estar haciendo algo mal.

El siguiente diagrama muestra el aumento dramático en el número de fallas de página blanda (los picos rojos) cuando la línea verde (el conjunto de trabajo) cayó de 50MB a 30MB.

Example showing the increase in soft page faults when the WorkingSet is reduced too low

actualización

Al final, terminamos ignorando el problema, ya que no tuvo impacto en el rendimiento tanto.

Más importante aún, SetProcessWorkingSetSizeEx hace no control de la WorkingSet actual, y es no relacionado de alguna manera con los errores de página suaves. Todo lo que hace es evitar las fallas de páginas duras, al evitar que el WorkingSet actual se pagine en el disco duro.

En otras palabras, si uno quiere reducir las fallas de página de software, SetProcessWorkingSetSizeEx no tiene absolutamente ningún efecto, ya que se refiere a las fallas de páginas duras.

Hay una gran descripción en "Windows a través de C/C++" (Richter) que trata de Windows con la memoria.

+1

¿Cómo espera que el sistema operativo mantenga más páginas en memoria de las que ha asignado? –

+0

@James McNellis Si el SO pudiera mantener más páginas en el WorkingSet, entonces el número de fallas de página disminuiría, lo que aceleraría drásticamente el programa. Tenemos 16 GB de RAM libre en el servidor, y no estaría de más tener 1 GB asignados permanentemente a este proceso (lo que reduciría el número de fallas de página suave a 0). – Contango

+0

@ Gravitas: ¿cómo se asigna y accede a la memoria? – ybungalobill

Respuesta

4

Las fallas de página son baratas y son de esperar. Las aplicaciones en tiempo real, los juegos de alta gama, el procesamiento de alta intensidad y la reproducción BluRay funcionan felizmente a toda velocidad con fallas de página. Las fallas de página no son la razón por la cual su aplicación es lenta.

Para descubrir por qué su aplicación es lenta, necesita hacer un perfil de aplicación de su aplicación.

Para responder específicamente a su pregunta: las fallas de página que se producen cuando acaba de recibir un GC.Collect() no son fallas de entrada de página, son fallas de página a demanda causadas por el hecho de que GC acaba de asignar un nuevo y enorme bloque de páginas a demanda para mover sus objetos. Las páginas de demanda cero no son atendidas desde su archivo de paginación y no incurren en costo de disco, pero siguen siendo fallas de página, por lo tanto, por qué se muestran en su gráfico.

Como regla general, Windows es mejor administrando los recursos de su sistema que usted, y sus valores predeterminados están muy ajustados para el caso promedio de los programas normales. De su ejemplo, está bastante claro que está utilizando un recolector de basura y, por lo tanto, ya descargó la tarea de tratar con los conjuntos de trabajo y la memoria virtual, y así sucesivamente, con la implementación del GC. Si SetProcessWorkingSetSize fuera una buena llamada API para mejorar el rendimiento del GC, la implementación del GC lo haría.

Mi consejo es perfilar su aplicación. La causa principal de la desaceleración en las aplicaciones administradas es escribir un código administrado incorrecto, no el GC que lo frena. Mejore el rendimiento del gran O de sus algoritmos, descargue el trabajo costoso mediante el uso de cosas como Future y BackgroundWorker e intente evitar hacer solicitudes sincrónicas a la red, pero, sobre todo, la clave para obtener su aplicación rápidamente es perfil .

+0

Utilizamos Microsoft Concurrency Visualizer para obtener una idea de lo que sucede en la aplicación. Al final, la pérdida de rendimiento no fue suficiente para preocuparse. – Contango

Cuestiones relacionadas