2012-08-30 20 views
5

¿Cómo configuro MinWorkingSet y MaxWorking para un proceso de .NET de 64 bits?¿Cómo configurar MinWorkingSet y MaxWorkingSet en un proceso de .NET de 64 bits?

p.s. Puedo fijar el conjunto MinWorkingSet y MaxWorking para un proceso de 32 bits, de la siguiente manera:

[DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize", SetLastError = true, CallingConvention = CallingConvention.StdCall)] 
internal static extern bool SetProcessWorkingSetSize(IntPtr pProcess, int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize); 

[DllImport("KERNEL32.DLL", EntryPoint = "GetCurrentProcess", SetLastError = true, CallingConvention = CallingConvention.StdCall)] 
internal static extern IntPtr MyGetCurrentProcess(); 

// In main(): 
SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, int.MaxValue, int.MaxValue); 
+1

¿Alguna razón por la que no utiliza la aplicación administrada? http://msdn.microsoft.com/en-us/library/system.diagnostics.process.minworkingset(v=vs.110) – rene

+0

En general, esta es una mala idea ya que el marco optimizará el tamaño del conjunto de trabajo. ¿Cuál es su requisito? – Maciej

+0

@Maciej Hemos ejecutado 3 semanas de análisis de latencia profunda en el programa, y ​​estamos viendo fallas de 250us en el programa debido a fallas de página de software. Estamos intentando aumentar el tamaño del conjunto de trabajo para reducir la cantidad de fallas de página suaves. – Contango

Respuesta

5

Todo lo que tiene que hacer es cambiar su declaración de este modo:

[DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize", 
    SetLastError = true, CallingConvention = CallingConvention.StdCall)] 
internal static extern bool SetProcessWorkingSetSize(IntPtr pProcess, 
    long dwMinimumWorkingSetSize, long dwMaximumWorkingSetSize); 

La razón se debe a la definition of the SetProcessWorkingSetSize function:

BOOL WINAPI SetProcessWorkingSetSize(
    _In_ HANDLE hProcess, 
    _In_ SIZE_T dwMinimumWorkingSetSize, 
    _In_ SIZE_T dwMaximumWorkingSetSize 
); 

Tenga en cuenta que no utiliza un (entero como de 32 bits) DWORD sino un SIZE_T, que is defined as:

El número máximo de bytes a los que puede apuntar un puntero. Úselo para un recuento de que debe abarcar todo el rango de un puntero. Este tipo se declaró en BaseTsd.h como sigue:

typedef ULONG_PTR SIZE_T; 

Esto significa que es un valor de 64 bits, por lo tanto, la capacidad de cambiar a un long y tienen la función de trabajo en sistemas de 64 bits. También, desde la sección de MSDN titulado "Common Visual C++ 64-bit Migration Issues":

size_t, time_t, y ptrdiff_t son valores de 64 bits en sistemas operativos Windows de 64 bits.

Sin embargo, esto presenta un poco de un dilema, en el sentido de que no desea tener que compilar ensambles específicos de la plataforma (que sería un PITA). Usted puede evitar esto mediante el aprovechamiento de la EntryPoint field en el DllImportAttribute class (que ya se está haciendo) para tener dos declaraciones de métodos:

[DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize", 
    SetLastError = true, CallingConvention = CallingConvention.StdCall)] 
internal static extern bool SetProcessWorkingSetSize32(IntPtr pProcess, 
    int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize); 

[DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize", 
    SetLastError = true, CallingConvention = CallingConvention.StdCall)] 
internal static extern bool SetProcessWorkingSetSize64(IntPtr pProcess, 
    long dwMinimumWorkingSetSize, long dwMaximumWorkingSetSize); 

Ahora usted tiene dos firmas independientes. Sin embargo, saber que firma para llamar sigue siendo un problema. No desea colocar controles condicionales en todas partes. Con ese fin, recomendaría crear un método que realice el control por usted y lo llame.

Querrá utilizar el Is64BitProcess property en el Environment class para tomar esta determinación. No use el Is64BitOperatingSystem property. Desea lo primero porque los procesos de 32 bits se pueden ejecutar en sistemas operativos de 64 bits, y desea asegurarse de que su código sea resistente a eso; solo verificando si el sistema que opera es de 64 bits no le da la imagen completa.

+2

O simplemente podría usar 'UIntPtr' y pasarlo así. – Mehrdad

5

No pinvoke esto, solo use la propiedad Process.CurrentProcess.MinWorkingSet directamente.

Probabilidades muy altas de que esto no hará ninguna diferencia. Las fallas de búsqueda suave son completamente normales y se resuelven muy rápido si la máquina tiene suficiente RAM. Toma ~ 0.7 microsegundos en mi computadora portátil.No puede evitarlos, es el comportamiento de un sistema operativo de memoria virtual demand_paged como Windows. Muy barato, siempre y cuando haya a free page readily available.

Pero si "blips" programa el rendimiento, entonces debe considerar la posibilidad de que no esté disponible y desencadene un error de página difícil en otro proceso. La falla de paginación se vuelve costosa si la página de RAM debe ser robada de otro proceso, su contenido debe ser almacenado en el archivo de paginación y debe ser reiniciado nuevamente a cero. Eso puede sumarse rápidamente, cientos de microsegundos no es inusual.

La ley básica de "no hay almuerzo gratis", necesita ejecutar menos procesos o comprar más RAM. Con la última opción, la opción correcta, 8 gigabytes te devuelve aproximadamente 75 dólares hoy. Robo completo.

+0

Esta es una respuesta absolutamente brillante, especialmente la sugerencia de que el primer acceso al elemento es el que dispara el error de la página suave. Estábamos observando un error de página suave 250us en el primer comando Dictionary.TryAdd(). – Contango

+0

Desafortunadamente, la configuración de MinWorkingSet no impide que la recolección de elementos no utilizados gen2 de .NET la recorte de todos modos (consulte el diagrama anterior en mi respuesta actualizada). – Contango

+0

Creo que tendré que configurar SE_INC_WORKING_SET_NAME y/o SE_INC_BASE_PRIORITY_NAME para que esto funcione, ya que GC.Collect() recorta el conjunto de trabajo de todos modos. Como el alcance de la pregunta ha cambiado, he publicado una nueva pregunta en http://stackoverflow.com/questions/12221541/is-there-a-way-to-expand-the-current-workingset-of-a -proceso-a-1gb. Deseo agradecerles sus consejos sobre qué causa exactamente las fallas de paginación suave. – Contango

Cuestiones relacionadas