Overloading operator new[] and operator[]
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9

Thread: Overloading operator new[] and operator[]

  1. #1

    Overloading operator new[] and operator[]

    I made my own allocator on top of malloc some years ago and decided to port it to windows for an app I am writing.

    Originally, I cared only about optimizing small allocations. However, for large allocations I really want to align things to 16 byte blocks. That way, I can take advantage of 128 bit move instructions.

    The quandary is, when my class defined operator new[] method gets called it's invariably for 4 more bytes than I'd think were warranted. I'm guessing but not certain that it's appending something like a pointer to its parent block to the end of the request. If that's the case, then obviously copying the extra bytes at the end between arrays would be disastrous. Anyone know if that's the case or is something else going on?

    I could probably do a workaround that tacked those bytes on the end of the allocation in new[] and copied them back to the original location in delete[] but that's the kind of thing that would be totally unportable and would completely fall apart every time the compiler or OS changed.

    Now, I know memcpy (theoretically) uses 128 bit instructions, but I want to have something that is simpler than that and can be inlined. memcpy works great for very large copies but not so much for stuff that's a few dozen bytes. I know someone will say let the optimizer take care of it, but unless you drop to inline assembly VC++ doesn't seem to ever generate anything but 32 bit instructions for user code (which is possibly a good thing).

  2. #2

    Re: Overloading operator new[] and operator[]

    Could this be a magic cookie to show what's in the array, or that it's an array? That would make sense, too. If that's the case I can igore it.

  3. #3

    Re: Overloading operator new[] and operator[]

    It looks like it sticks the size of the array into the first four bytes. I guess that sort of makes sense if array is considered its own structure. I'll have to keep that in mind during any copying, I guess.

  4. #4
    Join Date
    Apr 1999
    Posts
    27,446

    Re: Overloading operator new[] and operator[]

    Quote Originally Posted by originalfamousjohnsmith View Post
    I made my own allocator on top of malloc some years ago
    Since it was "some years ago", why not re-evaluate and decide if what you wrote is even necessary today?

    Regards,

    Paul McKenzie

  5. #5

    Re: Overloading operator new[] and operator[]

    Quote Originally Posted by Paul McKenzie View Post
    Since it was "some years ago", why not re-evaluate and decide if what you wrote is even necessary today?

    Regards,

    Paul McKenzie
    I already did. C++ default memory allocation sucks, and things like hoard are only somewhat better, even if I didn't mind paying 20k to use a 'free' open source project.

  6. #6
    Join Date
    Oct 2009
    Posts
    6

    Re: Overloading operator new[] and operator[]

    You are rich,
    I am sticky and jealous!

  7. #7

    Re: Overloading operator new[] and operator[]

    Quote Originally Posted by Thoungba View Post
    You are rich,
    I am sticky and jealous!
    But I do mind paying, as I am not rich at all.

  8. #8
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,100

    Re: Overloading operator new[] and operator[]

    Why does this come up again when we just recently had a whole discussion about it ?

    1) Profile first, most likely it's fast enough for your needs. 99% of the time the normal new/delete is more than fast enough. (do properly test in a RELEASE build as the debug versions of new/delete are slow because of the added overhead of tracking memoryleak detection and buffer overwrites).
    2) In the 1% of cases where it isn't fast enough, it's because multiple threads allocate memory from the same pool (change code to have each thread use it's own pool). Or because the code is inefficient by design (rewrite the code, don't blame slow allocation).
    3) Even if 1 and 2 aren't at issue. You're probably not good enough to write code that will reliably be faster than the default allocators. Maybe you can write somethign that does better on YOUR PC. But can you guarantee proper performance across the wide range of PC's your software will run on ?


    I have written a lot of code, I have reviewed a lot of code written by others (even other companies). Custom allocators quite often end up being slower as you migrate to newer PC's.


    Any allocation/deletion scheme invariably has 'bookkeeping' to store as well. Some libraries do that by maintaining datastructures that link a pointer to what it's pointing to, some libraries allocate a bit more than you ask and store the bookkeeping data before/or after the bytes you allocated yourself. Either system has pro's and con's. MS's CRT uses the 2nd method. This is the behaviour you're seeing. Don't assume that:
    Code:
    int* p1 = new int [16];
    int* p2 = new int [16];
    will result in 2 pointers where p2 will point right at the end of p1. This is not guaranteed for C++ in any compiler. If this happened to be the case in your old compiler, it was pure coincidence.

  9. #9

    Re: Overloading operator new[] and operator[]

    Quote Originally Posted by OReubens View Post
    Why does this come up again when we just recently had a whole discussion about it ?
    Well, I read every thread mentioning operator new[] and didn't find any discussion on it.

    Quote Originally Posted by OReubens View Post
    1) Profile first, most likely it's fast enough for your needs. 99% of the time the normal new/delete is more than fast enough. (do properly test in a RELEASE build as the debug versions of new/delete are slow because of the added overhead of tracking memoryleak detection and buffer overwrites).
    2) In the 1% of cases where it isn't fast enough, it's because multiple threads allocate memory from the same pool (change code to have each thread use it's own pool). Or because the code is inefficient by design (rewrite the code, don't blame slow allocation).
    3) Even if 1 and 2 aren't at issue. You're probably not good enough to write code that will reliably be faster than the default allocators. Maybe you can write somethign that does better on YOUR PC. But can you guarantee proper performance across the wide range of PC's your software will run on ?

    I have written a lot of code, I have reviewed a lot of code written by others (even other companies).
    I know people assume if you registered two weeks ago you have never coded anything, but most people have no idea how inefficient their allocators are. Especially for small allocations. Not just in time, but in space. My method has no memory overhead for small allocations, no heap contention or locks, and is extremely fast, much faster than anything else I know of, many of which are many times faster than the default already.

    Custom allocators quite often end up being slower as you migrate to newer PC's.
    Well if you don't know about multithreading and mindlessly lock everything the way everyone on these boards suggests then I am sure it will be slower, otherwise it's almost sure to be faster. You also just can't simply give each thread its own heap, to usefully do that it comes down to doing what I'm doing anyway or using an allocator that properly supports that like solaris or intel allocators - neither of which is an option for me.

    Quote Originally Posted by OReubens View Post
    Any allocation/deletion scheme invariably has 'bookkeeping' to store as well. Some libraries do that by maintaining datastructures that link a pointer to what it's pointing to, some libraries allocate a bit more than you ask and store the bookkeeping data before/or after the bytes you allocated yourself. Either system has pro's and con's. MS's CRT uses the 2nd method. This is the behaviour you're seeing. Don't assume that:
    Code:
    int* p1 = new int [16];
    int* p2 = new int [16];
    will result in 2 pointers where p2 will point right at the end of p1. This is not guaranteed for C++ in any compiler. If this happened to be the case in your old compiler, it was pure coincidence.
    Actually this is not the same thing at all. That part is (mostly) my job now, and in any sane would this will be invisible to the user.

    This is to keep track of how many constructors/destructors need calling. It makes sense but I was not really expecting that. I guess it has to keep track of that somewhere, though.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center