5

How do I set MinWorkingSet and MaxWorking set for a 64-bit .NET process?

p.s. I can set the MinWorkingSet and MaxWorking set for a 32-bit process, as follows:

[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);
4
  • 1
    Any reason you don't use the managed api? msdn.microsoft.com/en-us/library/… Commented Aug 30, 2012 at 19:30
  • In general, this is a bad idea as the framework will optimize the working set size. What is your requirement? Commented Aug 30, 2012 at 19:32
  • @Maciej We have run 3 weeks of deep latency analysis on the program, and we are seeing 250us blips in the program due to soft page faults. We are attempting to increase the working set size to reduce the amount of soft page faults. Commented Aug 30, 2012 at 20:05
  • 1
    sorry: minworkingset maxworkingset Commented Aug 30, 2012 at 20:11

2 Answers 2

8

Don't pinvoke this, just use the Process.CurrentProcess.MinWorkingSet property directly.

Very high odds that this won't make any difference. Soft paging faults are entirely normal and resolved very quickly if the machine has enough RAM. Takes ~0.7 microseconds on my laptop. You can't avoid them, it is the behavior of a demand_paged virtual memory operating system like Windows. Very cheap, as long as there is a free page readily available.

But if it "blips" your program performance then you need to consider the likelihood that it isn't readily available and triggered a hard page fault in another process. The paging fault does get expensive if the RAM page must be stolen from another process, its content has to be stored in the paging file and has to be reset back to zero first. That can add up quickly, hundreds of microseconds isn't unusual.

The basic law of "there is no free lunch", you need to run less processes or buy more RAM. With the latter option the sane choice, 8 gigabytes sets you back about 75 bucks today. Complete steal.

Sign up to request clarification or add additional context in comments.

3 Comments

This is an absolutely brilliant answer, especially the tip that the first element access is the one that trips the soft page fault. We were observing a 250us soft page fault on the first Dictionary.TryAdd() command.
Unfortuantely, setting MinWorkingSet doesn't stop the .NET gen2 garbage collection from trimming it back to the bare bones anyway (see the diagram above in my updated answer).
I think I might have to set SE_INC_WORKING_SET_NAME and/or SE_INC_BASE_PRIORITY_NAME to get this working, as GC.Collect() trims the working set down anyway. As the scope of the question has changed, I've posted a new question at stackoverflow.com/questions/12221541/…. I wish to thank you for your tips on exactly what causes soft paging faults.
7

All you have to do is change your declaration like so:

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

The reason is because of the definition of the SetProcessWorkingSetSize function:

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

Note that it doesn't use a DWORD (as 32-bit integer) but a SIZE_T, which is defined as:

The maximum number of bytes to which a pointer can point. Use for a count that must span the full range of a pointer. This type is declared in BaseTsd.h as follows:

typedef ULONG_PTR SIZE_T;

This means that it's a 64-bit value, hence the ability to change to a long and have the function work on 64-bit systems. Also, from the section of MSDN titled "Common Visual C++ 64-bit Migration Issues":

size_t, time_t, and ptrdiff_t are 64-bit values on 64-bit Windows operating systems.

However, this presents a bit of a dilemma, in that you don't want to have to compile platform-specific assemblies (that would be a PITA). You can get around this by taking advantage of the EntryPoint field on the DllImportAttribute class (which you're already doing) to have two method declarations:

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

Now you have two separate signatures. However, knowing which signature to call is still an issue. You don't want to place conditional checks everywhere. To that end, I'd recommend creating a method that performs the check for you and call that.

You'll want to use the Is64BitProcess property on the Environment class to make this determination. Don't use the Is64BitOperatingSystem property. You want the former because 32-bit processes can be run on 64-bit operating systems, and you want to make sure that your code is resilient to that; just checking to see if the operating system is 64 bit doesn't give you the entire picture.

1 Comment

Or you could just use UIntPtr and pass it as that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.