Seems that this implements a basic slab cache on top of malloc (or other) using C++ map data structures. Though I think maybe technically a slab cache allocates by dividing up a contiguous block of memory into specifically-sized chunks instead of piecing individual small chunks together in a queue. You can see in your example on your github page that your two 100-byte allocations are not at contiguous memory addresses.
I don’t know much about the speed of C++ things, but it would be nice to see some speed comparisons to malloc, since I think malloc does some binning/caching of its own instead of immediately returning stuff to the system.
Also, in allocate_memory(), if _alloc_fun() returns NULL due to underlying allocator (i.e., malloc) failing, it will still increment _used_mem, which will lead to incorrect accounting. It might also cause some problems when the NULL pointer is freed.
Thanks very much for your comment! I learnt a lot of thing.
Also, in allocate_memory(), if _alloc_fun() returns NULL due to underlying allocator (i.e., malloc) failing, it will still increment _used_mem, which will lead to incorrect accounting.
Yes, this is a bug and I have already fixed it, thanks!
Freeing a NULL pointer shouldn’t be an issue (at least when using free); the C99 standard draft says that:
The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs.
Sorry for my poor English. Because I use memory size as the key of the hashtable, and the key space of hashtable will affect performance. If user only uses some “fixed” size memory, it will have a better performance. Otherwise, the performance may be downgraded. For example, I use CUDA to do some mathematical computation, and only allocate memory in some size: 8K, 16K, the performance gets a remarkable improvement compared using the original CUDAMalloc* APIs, thanks!
What “fixed” size means in this case is that you expect to have many allocations/frees of the same size, i.e., you are allocating and freeing many objects of the same size throughout execution of the program.
And you very likely do not want to page-align ever allocation of, say, 100 bytes. It would be very inefficient if every allocation of 100 bytes was on a different 4K page.
Seems like it’s straightforward to read, well done! However, as a general advice, when the functionality is that simple you have to provide unit testing at least so you build up confidence in your own code, not only for yourself but for other people who want to use it.
Thanks very much for your suggestion! It is a really good habit of adding unit testing even it is just a toy. I will try to add unit testing later, thanks very much!
Seems that this implements a basic slab cache on top of malloc (or other) using C++ map data structures. Though I think maybe technically a slab cache allocates by dividing up a contiguous block of memory into specifically-sized chunks instead of piecing individual small chunks together in a queue. You can see in your example on your github page that your two 100-byte allocations are not at contiguous memory addresses.
I don’t know much about the speed of C++ things, but it would be nice to see some speed comparisons to malloc, since I think malloc does some binning/caching of its own instead of immediately returning stuff to the system.
Also, in allocate_memory(), if _alloc_fun() returns NULL due to underlying allocator (i.e., malloc) failing, it will still increment _used_mem, which will lead to incorrect accounting. It might also cause some problems when the NULL pointer is freed.
@bio_end_io_t:
Thanks very much for your comment! I learnt a lot of thing.
Yes, this is a bug and I have already fixed it, thanks!
Freeing a NULL pointer shouldn’t be an issue (at least when using
free); the C99 standard draft says that:Yes that is correct according to the standard. The issue in ump was with the accounting inside ump, but nanxiao fixed that.
I had a hard time parse this line. What does “fixed numbers” even mean? Does it mean the numbers have to be compile time constants?
Sorry for my poor English. Because I use memory size as the key of the hashtable, and the key space of hashtable will affect performance. If user only uses some “fixed” size memory, it will have a better performance. Otherwise, the performance may be downgraded. For example, I use CUDA to do some mathematical computation, and only allocate memory in some size: 8K, 16K, the performance gets a remarkable improvement compared using the original
CUDAMalloc*APIs, thanks!I still don’t understand what you are saying.
What is a ’“fixed” size memory?
Some magic numbers picked by tuning performance? Do I need compile time known constants? Can I give a number at runtime?
I guess you actually want to do a page aligned allocation. Is this what you are saying?
What “fixed” size means in this case is that you expect to have many allocations/frees of the same size, i.e., you are allocating and freeing many objects of the same size throughout execution of the program.
And you very likely do not want to page-align ever allocation of, say, 100 bytes. It would be very inefficient if every allocation of 100 bytes was on a different 4K page.
Yes, it should be “arbitrary”. Sorry for my poor English.
I update README, hope this can make clear. But sorry again for my poor English.
I think “arbitrary” is what you mean rather than “random”.
Seems like it’s straightforward to read, well done! However, as a general advice, when the functionality is that simple you have to provide unit testing at least so you build up confidence in your own code, not only for yourself but for other people who want to use it.
Thanks very much for your suggestion! It is a really good habit of adding unit testing even it is just a toy. I will try to add unit testing later, thanks very much!