News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Low Fragmentation Heap is slow

Started by zooba, November 19, 2006, 03:48:12 AM

Previous topic - Next topic

zooba

I've posted previously about an apparent memory leak in the LFH, and I've done some benchmarking today that show some interesting numbers:

_              |   1    |   2    |   4    |   8    |   16   |   32   |   64   |
Normal Heap    |    281 |    281 |    281 |    281 |    281 |    290 |    281 |
Low Frag Heap  |   2055 |   2054 |   2054 |   2056 |   1799 |   1569 |   2013 |

_              |  128   |  256   |  512   |  1024  |  2048  |  4096  |  8192  |
Normal Heap    |    281 |    286 |    285 |    540 |    540 |    542 |    542 |
Low Frag Heap  |   1640 |   1445 |   1668 |   1482 |   1696 |   1542 |   1795 |


The first and most obvious thing to notice is that the normal heap is much much quicker than the LFH. For allocations of less than 1024 bytes the normal heap is between 280-290 clocks, while the LFH ranges between 1445-2056. Above 1024 bytes, the normal heap approximately doubles in time sitting around 540 clocks, while the LFH has dropped to the mid 1000's. This is surprising since the LFH is supposed to be optimised for small allocations.

The other interesting point which I haven't included in the test program (though the modifications to test it are minimal) is that with serialisation disabled, the normal heap sits consistently around 370-390 clocks (the LFH won't work without serialisation).

Maybe someone else will find this interesting, not sure. However, I am definitely removing the LFH code from ASM Runtime. Should make for some decent speed improvements I think...

Cheers,

Zooba :U

(Note: LFH timings are only meaningful on Windows XP or later, since previous versions didn't have it. Win2K and earlier will display normal heap timings for both heaps)

[attachment deleted by admin]

hutch--

These are interesting numbers. From my own point of view, I would prefer OLE string for very large counts of variable length strings as they are properly designed for it. I know that a number of the conventional memory allocation techniques are faster but OLE manages massive counts of strings with no noticable problems of fragmentation.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

zooba

I've used the OLE string functions before when interfacing with VB and haven't had any problems except that many are exclusively designed for Unicode strings (ie. no directly equivalent ANSI version).

Do you have any suggestions on how I can test for fragmentation issues?

Cheers,

Zooba :U

hutch--

Here the two APIs fr byte sized OLE string.

        invoke SysAllocStringByteLen,0,ln
        invoke SysFreeString,strhandle


I have not has the slightest of problems with OLE string and this is after shoving millions of strings into OLE string. I don't know a way of testing fragmentation but you would get some idea by allocationg massive quantities of strings and track the entire system memory.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

zooba

Quote from: hutch-- on November 20, 2006, 11:25:01 AM
Here the two APIs fr byte sized OLE string.

        invoke SysAllocStringByteLen,0,ln
        invoke SysFreeString,strhandle


Yes, I suppose that's enough for simple allocation/deallocation. When I was using it for VB interfacing I often needed to copy a regular string into a BSTR. The SysAllocString function will copy a full string up to the first null terminator while the closest equivalent SysAllocStringByteLen for ANSI strings requires the length to be calculated first.

Quote from: hutch-- on November 20, 2006, 11:25:01 AM
I don't know a way of testing fragmentation but you would get some idea by allocationg massive quantities of strings and track the entire system memory.

A heap (I think) grows in increments of 4KB (or whatever the page size is) and doesn't reduce until you call HeapCompact. A non-growable heap just fails when it can't find space. So presumably allocating heaps of strings will simply take up heaps of memory. Is fragmentation really a big issue (ie. big enough for Microsoft to justify a LFH)? I don't think I've ever noticed the effects before, and I've done quite a lot of stuff using strings on a heap.

Cheers,

Zooba :U

zooba

Added a new bit to my test program which returns the number of bytes overhead for each allocation:

Quote               |   1    |   2    |   4    |   8    |   16   |   32   |   64   |
Normal Heap    |    273 |    556 |    556 |    556 |    552 |    552 |    551 |
    Overhead   |     15 |     14 |     12 |      8 |      8 |      8 |      8 |
Low Frag Heap  |   2040 |   2042 |   2040 |   2040 |   1756 |   1573 |   1986 |
    Overhead   |     15 |     14 |     12 |      8 |      8 |      8 |      8 |

               |  128   |  256   |  512   |  1024  |  2048  |  4096  |  8192  |
Normal Heap    |    552 |    551 |    547 |    532 |    532 |    521 |    538 |
    Overhead   |      8 |      8 |      8 |      8 |      8 |      8 |      8 |
Low Frag Heap  |   1654 |   1446 |   1683 |   1483 |   1711 |   1546 |   1820 |
    Overhead   |      8 |      8 |      8 |      8 |      8 |      8 |      8 |

It appears the minimum allocation size is 16 bytes with 8 bytes of required overhead. There is no difference between standard heap and LFH, though the HeapWalk function predates the LFH, so it may not compute it properly.

Cheers,

Zooba :U

[attachment deleted by admin]