Advertisement

Unusually high memory usage

Started by September 26, 2018 01:20 AM
4 comments, last by DividedByZero 6 years, 4 months ago

Hi guys,

I have just noticed my project is using quite a bit of memory and I have narrowed it down to draw calls.

I am drawing quads with 32px by 32px images with R8B8G8A8 formatting. Back buffer is formatted the same also.

So in theory the sprite is using 4K of RAM.

I notice though, that each individual draw call I make is using 13MB of RAM. Draw 10 quads and it blows up to 130MB of RAM (Release mode).

I checked using the VS graphical debugger and the render sequence is extremely lean at only a couple of calls.

My draw routine is pretty compact also;


	// Draw sprite
	float attributes = 4.0f;		// X, Y, U, V
	unsigned int stride = (unsigned int)(sizeof(float) * attributes);
	unsigned int offset = 0;
	d3dContext->IASetInputLayout(d3dInputLayoutDefault);
	d3dContext->IASetVertexBuffers(0, 1, &d3dVertexBufferDynamic, &stride, &offset);
	d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
	d3dContext->Draw(6, 0);

The RAM usage is the same if I use single or double buffering on the back buffer and I am not using any surfaces.

Any ideas why each draw call costs 13 MB? Or is this normal behaviour that I just haven't picked up on before?

Thanks in advance :)

You mean, if you wrap the posted code in a for loop that repeats it 100 times, then Windows task manager will say that your app is using 1.3 gigs of RAM?

1 hour ago, DarkRonin said:

I am drawing quads with 32px by 32px images with R8B8G8A8 formatting. Back buffer is formatted the same also.

So in theory the sprite is using 4K of RAM.

When creating these textures, it should allocate ~4KB of RAM.  The Draw and IASet* calls that you've posted only write small GPU instructions into a command buffer though - they don't allocate any texture data...

Advertisement
3 hours ago, Hodgman said:

You mean, if you wrap the posted code in a for loop that repeats it 100 times, then Windows task manager will say that your app is using 1.3 gigs of RAM?

When creating these textures, it should allocate ~4KB of RAM.  The Draw and IASet* calls that you've posted only write small GPU instructions into a command buffer though - they don't allocate any texture data...

Hi there, thanks for the reply.

Further testing, it seems to taper out to ~160 MB RAM usage, whether it be 200 sprites or 2000. So maybe I am chasing something that isn't really an issue. Just seemed alarming that every draw call (was doing 10 or so) jumped RAM usage by exactly 13MB each time.

Probably a non-event.

So you have to be a bit careful when looking at the overall memory usage of your process. There are lots of things can allocate virtual memory inside of your process, of which your own code is just one. The OS and its various components might allocate things in your address space, third-party libraries linked into your code or loaded as a DLL can allocate, and then of course there's a very heavy D3D runtime and a user-mode driver loaded into your process. Sometimes these other components will allocate memory as a direct result of your code (for instance, if you create a D3D resource) but in many other cases it will do so indirectly. The driver might need some memory for generating command buffers, or it might have a pool of temporary memory that it draws from when you map a dynamic buffer. Basically this means that while it's always a good idea to keep an eye on your memory usage, you probably need more information than what task manager gives you if you really want to know what's going on.

For the memory directly allocated by your own code, writing your own simple tools can be really useful. Generally you want to have all kinds of information that's specific to your game or engine, such as "how much memory am I using for this one level?" or "how much memory am I using for caching streamed data?". As for keeping track of everyone else's allocations, for that the best tool is ETW. With that you can trace the callstack of every call to VirtualAlloc, which can give you clues as to what's going on. Unfortunately there will be things for which you don't have PDB's, but you can at least get symbols for Microsoft DLL's using their public symbol server. The new PIX for Windows also has a built-in memory capture tool that can give you the same information, which it does by using ETW under the hood. 

Awesome info MJP. A few things to look at there :)

This topic is closed to new replies.

Advertisement