windowsgraphicsdirectxvulkan

Why does Windows only allow your GPU to use half of your RAM?


The following is what Vulkan Capability viewer shows for my computer:

MEMORY HEAP 0
    DEVICE SIZE 8321499136
    FLAGS
        DEVICE_LOCAL_BIT
        MULTI_INSTANCE_BIT

    MEMORY TYPE 0
        DEVICE_LOCAL_BIT
    MEMORY TYPE 1
        DEVICE_LOCAL_BIT

MEMORY HEAP 1
    DEVICE SIZE 16760438784
    FLAGS
    NONE

    MEMORY TYPE 0
        HOST_VISIBLE_BIT
        HOST_COHERENT_BIT
    MEMORY TYPE 0
        HOST_VISIBLE_BIT
        HOST_COHERENT_BIT

Heap 0 is my GPU device, which has 8GB. Heap 1 is supposed to be my CPU RAM. I have 32GB and that's what shows in my task manager on Windows, but only half of that (16GB) shows in the Vulkan memory heap description with Vulkan. I looked up why this is, and I found in a Calculating Graphics Memory page on the Microsoft page:

Before VidMm can report an accurate account to clients, it must first calculate the total amount of graphics memory. VidMm uses the following memory types and formulas to calculate graphics memory numbers:

Total system memory

This value is the total amount of system memory accessible to the operating system. Memory that the BIOS allocates doesn't appear in this number. For example, a computer with a 1 GB DIMM (1,024 MB) that has a BIOS that reserves 1 MB of memory appears to have 1,023 MB of system memory.

Total system memory that's available for graphics use

This value is the total amount of system memory that is dedicated or shared to the GPU. This number is calculated as follows:
C++ 

TotalSystemMemoryAvailableForGraphics = MAX((TotalSystemMemory / 2), 64MB)

The link is here.

I was wondering why this is. Only half your RAM is every available to use with both Vulkan and DirectX, or graphics API? This is apparently what VidMm reports. I don't know what VidMm, but either DirectX or Vulkan consults this to see how much memory is available, and it always reports half of your RAM only?

In my case I have a dedicated GPU with 8GB, which is reported correctly, and the system RAM is reported as HALF of what I actually have, 32GB divided by 2. What would happen if it was an iGPU? The device would only be able to use half of that system memory? Meaning only half of the device memory would be able to be used? This is only on Windows and now other operating systems?


Solution

  • VidMM is the Video Memory Manager that is a part of the DirectX Graphics Kernel. Back in XDDM, graphics drivers had to implement their own memory allocators. This was rather messy, driver developers by their nature are good at hardware, they're less good at memory allocation (something that people have entire PhDs in). This meant that the memory allocators of different vendors could vary wildly in how well they performed. Meanwhile, Microsoft is quite good at writing memory allocators since they already have to do it for Windows. With WDDM, Microsoft decided to move GPU memory allocation from the IHV's responsibility onto themselves. This freed up GPU vendors to focus on other aspects of the driver, and for users to have a unified experience across devices.

    The restriction on system memory for graphics usage isn't limiting how much memory you can use, it's limiting how much you can use within the graphics APIs. The system doesn't want to starve other processes of memory, so at some point it has to cut off allocations. Microsoft decided that half of system memory was a sufficient cutoff. This value is likely completely arbitrary.

    The Shared System Memory isn't just the memory that you can allocate for staging buffers. In the background Windows and the display drivers are capable of dynamically moving allocations to and from the GPU at will. The Video Scheduler (VidSch) will determine what resources are needed to run a command list and request that the driver setup DMA actions to get those resources onto the GPU, while also evicting unused resources from the GPU. Obviously this will absolutely kill performance, but at least your system doesn't crash.

    What would happen if it was an iGPU?

    In that case the Display Miniport Driver would report that its memory is PopulatedFromSystemMemory. This will dedicate a portion of the TotalSystemMemoryAvailableForGraphics to be exclusively used for the GPU. My understanding is that this memory would be entirely inaccessible to applications to use from HeapAlloc or VirtualAlloc, meanwhile the SharedSystemMemory can be encroached upon by applications for general purpose work as well as allocated specifically using the graphics APIs.

    This is done to ensure that there is always a portion of memory available to GPU.

    This is only on Windows and now other operating systems?

    I'm only familiar with Windows, but I'd be surprised if other operating systems didn't have restrictions in place to limit graphics memory usage.