Jump to content

  • Log In with Google      Sign In   
  • Create Account

What improves better memory performance?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
41 replies to this topic

#1 SIC Games   Members   -  Reputation: 617

Like
0Likes
Like

Posted 06 September 2012 - 10:26 AM

What imrpoves performance in memory management? By using the keyword New or malloc? What if one allocated memory doesn't get deleted - will it literally screw the memory leaving it too fragmented or after the computer restart the memory will automatically free anything it has resides?

New and Malloc are termed as Heap, right? Stack Heap, Pool Heap - etc?

Have a great day everyone! I wanted to know about your perspective on better performance in memory.

Game Engine's WIP Videos - http://www.youtube.com/sicgames88


Sponsor:

#2 Cornstalks   Crossbones+   -  Reputation: 6995

Like
6Likes
Like

Posted 06 September 2012 - 10:40 AM

What imrpoves performance in memory management? By using the keyword New or malloc?

Doesn't matter (or at least it shouldn't). If you're using C++, use new.

What if one allocated memory doesn't get deleted - will it literally screw the memory leaving it too fragmented or after the computer restart the memory will automatically free anything it has resides?

On a modern system, the OS will free all "un-freed" memory when the program terminates, so you shouldn't need to restart your memory to reclaim the un-freed memory. But it's still bad practice and can lead to your program running out of available memory while it's executing.

New and Malloc are termed as Heap, right? Stack Heap, Pool Heap - etc?

new and malloc allocate memory on the heap.

Have a great day everyone! I wanted to know about your perspective on better performance in memory.

The best memory performance will come from allocating and freeing as little as possible. If you can re-use a chunk of memory, that's better in terms of performance than freeing it and reallocating another chunk. Allocating memory is a very slow and expensive operation. Accessing memory is quite slow too, unless it's in the cache, which is why cache-misses and cache performance are often a critical bottleneck in modern applications (so try to maintain some temporal and spatial locality when accessing memory to improve cache performance).
[ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

#3 fastcall22   Crossbones+   -  Reputation: 4345

Like
4Likes
Like

Posted 06 September 2012 - 10:45 AM

What imrpoves performance in memory management?

Pooling small frequent allocations into larger but infrequent allocations, favoring the stack over the heap whenever possible, minimizing the number of calls to malloc/new, and separating allocations into differnet heaps depending on expected object lifetimes*, utilizing separate heaps to improve cahce locality, and etc...

Cornstalks answered the rest...


*I'm not sure about this one; I've read somewhere -- can't remember where -- of a certain lifetime-based allocation algorithm that were used in some console games.

Edited by fastcall22, 06 September 2012 - 10:45 AM.

c3RhdGljIGNoYXIgeW91cl9tb21bMVVMTCA8PCA2NF07CnNwcmludGYoeW91cl9tb20sICJpcyBmYXQiKTs=

#4 Radikalizm   Crossbones+   -  Reputation: 2889

Like
4Likes
Like

Posted 06 September 2012 - 10:46 AM

New and malloc are both used for dynamic memory allocation on the heap, new is C++ specific while malloc is available in both C and C++. Mixing of both new and malloc in C++ is heavily discouraged, so it's best to stick to the new keyword for standard dynamic memory allocation in C++.

Not releasing memory with free or delete causes what we call a memory leak when said memory becomes unreachable (ie. the application has no access to a pointer which points to this memory). The memory is now unavailable for use by both your application and the operating system, and thus cannot be reassigned to another application for as long as the original application is running.
When the original application exits however the operating system will reclaim all memory allocated by that application. This however does not mean that you shouldn't take memory leaks seriously as they are still potentially hazardous.

Memory fragmentation is an issue which will occur in standard dynamic allocation whether you have memory leaks or not, chunks of memory which are all allocated in one new or malloc call however will be contiguous in memory. The only way to completely remove memory fragmentation is by doing linear allocation on a pre-allocated memory pool for example (like when working with the stack), but this allocation scheme is absolutely not suited as a general purpose allocator.


These concepts are all very elementary C++ concepts. I know you're writing a game engine, so I find it very odd that these things are new to you.

Edited by Radikalizm, 06 September 2012 - 10:47 AM.

I gets all your texture budgets!


#5 lride   Members   -  Reputation: 633

Like
0Likes
Like

Posted 06 September 2012 - 03:31 PM

Try to avoid new or delete. Allocating memory from a pool of heap is a very slow operation.
Automatic variables are much faster
An invisible text.

#6 SIC Games   Members   -  Reputation: 617

Like
0Likes
Like

Posted 06 September 2012 - 03:34 PM

New and malloc are both used for dynamic memory allocation on the heap, new is C++ specific while malloc is available in both C and C++. Mixing of both new and malloc in C++ is heavily discouraged, so it's best to stick to the new keyword for standard dynamic memory allocation in C++.

Not releasing memory with free or delete causes what we call a memory leak when said memory becomes unreachable (ie. the application has no access to a pointer which points to this memory). The memory is now unavailable for use by both your application and the operating system, and thus cannot be reassigned to another application for as long as the original application is running.
When the original application exits however the operating system will reclaim all memory allocated by that application. This however does not mean that you shouldn't take memory leaks seriously as they are still potentially hazardous.

Memory fragmentation is an issue which will occur in standard dynamic allocation whether you have memory leaks or not, chunks of memory which are all allocated in one new or malloc call however will be contiguous in memory. The only way to completely remove memory fragmentation is by doing linear allocation on a pre-allocated memory pool for example (like when working with the stack), but this allocation scheme is absolutely not suited as a general purpose allocator.


These concepts are all very elementary C++ concepts. I know you're writing a game engine, so I find it very odd that these things are new to you.


Yes, I understand the concepts are elementary - within 3 months now I've been refreshing my knowledge in C++. I've not touched C since I was 7 years old. Teenage years I've been mostly in HTML, PERL, and other web-based programming. 2001-2011 I've been not programming because getting over depression and couseling sessions. 2011, met my wife and happy as a clam. So, yes; I'm refreshing quickly as possibly to catch up with the professional game industry. It's not crazy to remember pieces of code from a dream. I woke up last night from a dream discussing about TCHAR with another person in my dream. Guardian Angels sending some kind of crytic message - who knows. All I know is I got to catch up to the professional game gurus. This is why I'm obtaining every bit of information possible - John just didn't wake up and say "Doom - 3D first game engine. I have all the code inside my brain." He had to learn it from books; from others; from other sources and trial and error. Albert Einstein was perhaps showed the formula that would equate to E=MC squared. I'm a spiritualist; my views may differ upon others spiritual views on the forum.

Game Engine's WIP Videos - http://www.youtube.com/sicgames88


#7 Radikalizm   Crossbones+   -  Reputation: 2889

Like
4Likes
Like

Posted 06 September 2012 - 04:01 PM

Try to avoid new or delete. Allocating memory from a pool of heap is a very slow operation.
Automatic variables are much faster


Define automatic variables (I assume you're talking about using the stack?)

It's definitely true that allocating on the heap can be slow, but completely abandoning dynamic allocation sounds quite drastic to me, and is mostly easier said than done.
The important thing is to find a correct balance between stack and heap usage, and to know which situations call for stack allocation and which call for heap allocation.

Also, allocating from a memory pool doesn't have to be slow, it's all dependent on what kind of allocation scheme you use. It's perfectly possible to do very fast stack-like allocation on a pre-allocated memory pool. There's an interesting paper from DICE about this which can be found here


@SIC:

There's no need to drag spirituality into this, I'm just saying that it might be a good idea to start off with something less complex and gigantic than a game engine + tools when you need to get reacquainted with basic C/C++ concepts.

Edited by Radikalizm, 06 September 2012 - 04:04 PM.

I gets all your texture budgets!


#8 frob   Moderators   -  Reputation: 21430

Like
5Likes
Like

Posted 06 September 2012 - 04:32 PM

This is one area where memory pools can be useful.

It is not a topic for beginners to dive in to, but it is useful to know about.

Allocating from the global heap can be slow. It isn't necessarily slow, but it usually is.

That means that using the global heap when making a large number of small allocations, or when making frequent allocations/deallocations, application performance will be sub-optimal.

Many games will allocate a huge blocks of memory from the OS's global heap, then use that memory pool for their own purposes. The upside is faster allocations. The downside is memory fragmentation can destroy the program.

Dealing with the resulting memory fragmentation is definitely NOT a beginner topic; doing it wrong will crash your game in fun and exciting ways. But for major games, the added performance is often worth the cost.

Boost has a pool allocation system (found here) if you really want to read up on it.

Again, it is NOT something recommended for beginners, and generally not recommended at an intermediate skill level unless you really have a demonstrated need for it.
Check out my personal indie blog at bryanwagstaff.com.

#9 SIC Games   Members   -  Reputation: 617

Like
0Likes
Like

Posted 06 September 2012 - 05:03 PM

So, a rule of thumb is to consistantly make sure no memory leaks because it can cause performance slow down. Got it. Additional notes, keep proper heaps so there's less fragmentation in memory - got it.

Game Engine's WIP Videos - http://www.youtube.com/sicgames88


#10 swiftcoder   Senior Moderators   -  Reputation: 10060

Like
3Likes
Like

Posted 06 September 2012 - 05:15 PM

The memory is now unavailable for use by both your application and the operating system, and thus cannot be reassigned to another application for as long as the original application is running.

This is not really true on desktop operating systems. In practice, when some other process needs more memory than is currently available, the virtual memory system will stash a few of your memory pages to disk, and grant that physical memory to the other process. Obviously, this is all pretty transparent to both applications.

On a console or mobile device, there often isn't a virtual memory system, in which case your statement is correct.

Tristam MacDonald - Software Engineer @Amazon - [swiftcoding]


#11 Radikalizm   Crossbones+   -  Reputation: 2889

Like
1Likes
Like

Posted 06 September 2012 - 05:33 PM


The memory is now unavailable for use by both your application and the operating system, and thus cannot be reassigned to another application for as long as the original application is running.

This is not really true on desktop operating systems. In practice, when some other process needs more memory than is currently available, the virtual memory system will stash a few of your memory pages to disk, and grant that physical memory to the other process. Obviously, this is all pretty transparent to both applications.

On a console or mobile device, there often isn't a virtual memory system, in which case your statement is correct.


Well yeah, but for simplicity's sake I thought it would be better not to include an explanation of how paging works as it wasn't needed to explain the basic idea of a memory leak :)

I gets all your texture budgets!


#12 Cornstalks   Crossbones+   -  Reputation: 6995

Like
1Likes
Like

Posted 06 September 2012 - 05:33 PM


The memory is now unavailable for use by both your application and the operating system, and thus cannot be reassigned to another application for as long as the original application is running.

This is not really true on desktop operating systems. [...relevant stuff...]

This is kind of splitting hairs. I think you're focusing more on the physical RAM (i.e. where your memory is), whereas Radikalizm I think was focusing more on the "big picture" of overall memory use (where you have a limited amount to work with on a computer, regardless of where that virtual memory physically is). So I'd say you're both right and both bring up good points.
[ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

#13 SIC Games   Members   -  Reputation: 617

Like
0Likes
Like

Posted 06 September 2012 - 05:54 PM

It's okay guys! It's all good! It's all good advice because Virtual memory is good to know when creating a game to work on Desktop; and different allocation way to handle of memory for a mobile and a console game. I think it'll be just best practice to ensure that I deallocate the memory - if I ever do port the engine to a console or phone. It's just good practice I think. Regardless of virtual or just physical - I think it just shows proper effective coding. Which I gotta get the ebook of Effective Coding on amazon. Currently, I'm aiming at effective and proficient coding techniques.

Game Engine's WIP Videos - http://www.youtube.com/sicgames88


#14 swiftcoder   Senior Moderators   -  Reputation: 10060

Like
2Likes
Like

Posted 06 September 2012 - 06:02 PM

where you have a limited amount to work with on a computer, regardless of where that virtual memory physically is

On your average 64-bit desktop with a 500+ GB harddrive, you could easily use several hundred gigabytes of memory - despite only having < 16 GB of physical RAM (you also may be able to allocate several terabytes of memory, provided you don't actually write any data to it).

My point is that you don't free memory on a desktop OS because you are worried about running out, you free memory to avoid the performance hit caused by unnecessary paging.

Tristam MacDonald - Software Engineer @Amazon - [swiftcoding]


#15 phil_t   Crossbones+   -  Reputation: 3928

Like
2Likes
Like

Posted 06 September 2012 - 06:23 PM

So, a rule of thumb is to consistantly make sure no memory leaks because it can cause performance slow down. Got it. Additional notes, keep proper heaps so there's less fragmentation in memory - got it.


"Got it" ... but do you understand the reason? If you're trying to learn, you should be able to explain why.

I actually don't think anyone said memory leaks cause a performance slow down. That's kind of a vague statement anyway. A more accurate, concrete statement would be that memory leaks can cause future allocations to fail because there will no longer be sufficient virtual memory left (although on a 64-bit machine, this may take "forever"). So your program will run out of memory and crash or lose functionality or end up in a corrupt state (depending on how well you handle the allocation failures). However, on the way there, it could likely cause performance problems if there is a lot of paging to disk.

Someone did say that lots and lots of small heap allocations (regardless of whether you're leaking the memory) could cause performance issues, and that is true. Allocating from the heap can be a *relatively* slow operation in c++. It's not typically something you should be worried about at this stage though.

It's definitely more than "best practice" to ensure that you deallocate memory. It's necessary if you are writing any quality code - something you'd want to ship and have other people use.

Edited by phil_t, 06 September 2012 - 06:26 PM.


#16 Karsten_   Members   -  Reputation: 1611

Like
1Likes
Like

Posted 06 September 2012 - 06:32 PM

Hate to say it, but this where I think GC languages like Java and C# do quite well.

Basically rather than allocating and deallocating memory as they go along, they allocate the memory but then only deallocate at certain points and in which case they clean up a lot of memory in one pass which is ultimately quicker.

If you do look into memory pools, stuff can get quite complicated so sometimes it might be nice to leave it to the GC platform's memory pool.

Frankly I prefer the simplicity of smart pointers, but they are ultimately "inefficient".
By using C++.NET you can perhaps get best of both worlds, by using auto_handle<T> to get deterministic disposal of memory to implement patterns requiring RAII but also garbage collected memory using gcnew.

Edited by Karsten_, 06 September 2012 - 06:33 PM.

Mutiny - Open-source C++ Unity re-implementation.
Defile of Eden 2 - FreeBSD and OpenBSD binaries of our latest game.


#17 SIC Games   Members   -  Reputation: 617

Like
0Likes
Like

Posted 06 September 2012 - 06:49 PM

Phil_t, I can easily comprehend than what what you are saying. Yes, it is a necessasity in coding to ensure to deallocate memory regardless of what OS. I don't care if a person is running a HAL 9000 or whatever - still inside my mind it's proper coding effectiveness. Everyone is right due to their opinion based on experience. So, yes I "got it" and I comprehend. If I was a bit confused - I would ask more questions; right? That's what a person learning would naturally do, right?

Good job everyone for giving some handful advice. This is why you have I've gave you positive reputation points.

Game Engine's WIP Videos - http://www.youtube.com/sicgames88


#18 Hodgman   Moderators   -  Reputation: 30415

Like
8Likes
Like

Posted 06 September 2012 - 09:30 PM

Hate to say it, but this where I think GC languages like Java and C# do quite well.

GC's are absolutely horrible in games. The collection process itself is a cache-miss nightmare (traversing the object graph is basically random-access, making it worst-case for caches, making it memory bound, making it run at about 1/800th efficiency compared to regular CPU logic) and the amount of work it has to do is hidden from the programmer and unpredictable. Sometimes you'll just have a huge spike in your frame time because the GC decided to go on a garbage hunt that frame... So then if you're lucky, you can put time-limits on your GC so it doesn't blow your frame times, and explicitly call it an an appropriate moment... However, then if it needs to run for a long time and you've capped it, that means that memory is going to start filling up with garbage and you run out of memory! So now you're left to go and rewrite all your code so as to not produce any garbage, using persistent pools etc, just like you would have in C/C++ code that avoids new/delete anyway... and we come full circle to the advice of 'don't allocate memory'.

#19 larspensjo   Members   -  Reputation: 1540

Like
1Likes
Like

Posted 07 September 2012 - 03:24 AM

GC's are absolutely horrible in games.

For hard real time, it is definitely a problem. For soft real time, there are possibilities. It depends on whether a game is hard or soft real time. Action games, like shooters, that depend on a steady FPS and consistent repeatable responses may certainly be a problem.

I have a MMO RPG server designed to support 10000+ players. Being a RPG, rather than a shooter, lowers the requirements. The server is programmed in Go, which is entirely based on garbage collection. Doing tests for 1000 players shows a steady load of approximately 10% on the target machine. True, it is a synthetic test, and not a proof that it will work in a real situation. But it looks very promising so far. I should also admit that the design of the server has been influenced by the GC mechanism. That is, data is preferentially re-used instead of thrown away. But that is not different to usual C/C++.

I think the aversion against GC is a little too strong here and there. Especially from card core C/C++ programmers.
Current project: Ephenation.
Sharing OpenGL experiences: http://ephenationopengl.blogspot.com/

#20 lawnjelly   Members   -  Reputation: 429

Like
2Likes
Like

Posted 07 September 2012 - 04:54 AM

Fixed size memory pools FTW. They are great.Posted Image

The downsides are you have to (typically) know in advance how many of the objects maximum you will want worst case scenario. In addition the memory preallocated for the pool is not available for other uses.

Upsides are they are blazingly fast, constant time allocation and deallocation, there is no fragmentation, and provided you choose the maximums correctly your program CANNOT crash due to an allocation failure.

You can also implement your own heap with buckets but it's not something I'm a fan of.

You can also (in c++) override new and delete to keep track of your allocations. You can use different heaps / counters for different modules, and budget your memory between them. Very useful on consoles and limited memory devices. This can also report to you any memory leaks on closing, which module and which file they are from.

Other tricks are things like, when you load in a game level, load it as a binary file laid out in usable form in memory. Then fixup the pointers within it from offsets within the file to actual locations in memory. This gives you super fast loading, no fragmentation, and cache coherency. And of course level size etc is one of the biggest 'changables' within a game, so if you can isolate this down to one allocation, you shouldn't really need to do much else in the way of allocation. And even for this you can just pre-allocate a big chunk for the biggest level size, that's what I've tended to do on console-like environments.

Of course this is for game code, where stability and speed are paramount. For tools and apps I'll be a lot more lax, and use dynamic allocation etc (sometimes I don't even override new and delete, when I'm feeling like living life close to the edge Posted Image ).

It's also worth mentioning that there are some allocations you can't avoid, depending on the OS - API allocations such as directx and opengl. You can of course use pooling systems with your API resources too. In addition on consoles you can often completely avoid this problem by using a resource directly from memory as they may be UMA or give you more control over memory.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS