views:

113

answers:

4

Is there anything wrong with the optimization of overloading the global operator new to round up all allocations to the next power of two? Theoretically, this would lower fragmentation at the cost of higher worst-case memory consumption, but does the OS already have redundant behavior with this technique, or does it do its best to conserve memory?

Basically, given that memory usage isn't as much of an issue as performance, should I do this?

+6  A: 

The default memory allocator is probably quite smart and will deal well with large numbers of small to medium sized objects, as this is the most common case. For all allocators, the number of bytes requested is never always the amount allocated. For example, if you say:

char * p = new char[3];

the allocator almost certainly does something like:

char * p = new char[16];   // or some minimum power of 2 block size

Unless you can demonstrate that you have an actual problem with allocations, you should not consider writing your own version of new.

anon
Some memory allocators have different pools of various sizes. For small allocations a pool of small width blocks would be more efficient than the pool of large blocks.
Thomas Matthews
+3  A: 

Should you do this? No.

Two reasons:

  • Overloading the global new operator will inevitably cause you pain, especially when external libraries take dependency on the stock versions.
  • Modern OS implementation of the heap already take fragmentation into consideration. If you're on Windows, you can look into "Low Fragmentation Heap" if you have a special need.

To summarize, don't mess with it unless you can prove (by profiling) that it is a problem to begin with. Don't optimize pre-maturely.

Alienfluid
1) It hasn't so far!2) I'm not on Windows.3) Optimizing prematurely is fun.4) I was just curious :)
Clark Gaebel
+4  A: 

You should try implementing it for fun. As soon as it works, throw it away.

FredOverflow
I did. Thank you!
Clark Gaebel
@wowus Already finished? Wow, that was fast :)
FredOverflow
A: 

I agree with Neil, Alienfluid and Fredoverflow that in most cases you don't want to write your own memory allocator, but I still wrote my own memory allocator about 15 years and refined it over the years (first version was with malloc/free redefinition, later versions using global new/delete operators) and in my experience, the advantages can be enormous:

  • Memory leak tracing can be built in your application. No need to run external applications that slow down your applications.
  • If you implement different strategies, you sometimes find difficult problems just switching to a different memory allocation strategy
  • To find difficult memory-related bugs, you can easily add logging to your memory allocator and even further refine it (e.g. log all news and deletes for memory of size N bytes)
  • You can use page-allocation strategies, where you allocate a complete 4KB page and set the page size so that buffer overflows are caught immediately
  • You can add logic to delete to print out if memory is freed twice
  • It's easy to add a red zone to memory allocations (a checksum before the allocated memory and one after the allocated memory) to find buffer overflows/underflows more quickly
  • ...
Patrick
Alienfluid
I tried all the Microsoft utilities (Application Verifier, UMDH, Gflags, ...) and I couldn't achieve the same results as with my own memory allocator. For example, the Microsoft tools can only take memory snapshots and then compare two snapshots, and not report the leaks at the end of the application including the call stack, as I can do. Additional factors to take into account: my applications can take easily 500MB memory, up to several GB of memory (in a 64-bit env). Working with memory snapshots is then simply impossible.
Patrick
I'm using gcc, and what you're saying is done by Valgrind. I think it was a fun little project overloading the global new/delete, but impractical. Therefore, I'll go with trusting the system allocator.
Clark Gaebel
Patrick - Application Verifier will trace all allocations (include stack trace for alloc/free) and break into the debugger if any memory was either not freed or double freed on application exit. Give it a shot again :).
Alienfluid
@Alienfluid, I tried Application Verifier, but I couldn't get it to report memory leaks. I posted a question (http://stackoverflow.com/questions/2955858/how-to-use-application-verifier-to-find-memory-leaks) but I got no real answer (only answers to use other leak-finding mechanisms, or not to write leaks at all). Tips?
Patrick