2024-03-01 14:21:52 -05:00
|
|
|
# allocPool - A simple & high performance object pool using modern C++
|
|
|
|
|
2024-03-01 15:19:52 -05:00
|
|
|
This is allocPool, a pool of objects in a single header file that allow you to
|
|
|
|
avoid expensive allocations during runtime. This preallocates objects in the
|
|
|
|
constructor (with threads) then offers you two functions: `getPtr()` and `returnPtr(ptr)`.
|
2024-03-01 14:21:52 -05:00
|
|
|
|
|
|
|
Using C++ concepts, we can use templates and require the class given to have a
|
2024-03-02 12:48:49 -05:00
|
|
|
default constructor and to have a `.reset()` function. It will be used to clean the
|
2024-03-01 14:21:52 -05:00
|
|
|
objects before giving them to another caller.
|
|
|
|
|
2024-03-02 12:48:49 -05:00
|
|
|
We avoid false sharing by keeping a high amount of work per thread. This should
|
|
|
|
lead to cache lines not being shared between threads. While this pool uses a hashmap
|
2024-03-03 00:11:31 -05:00
|
|
|
and a pivot to make `returnPtr(ptr)` extremely fast, the construction's main bottleneck is
|
2024-03-02 12:48:49 -05:00
|
|
|
in the locking and unlocking of the hashmap's mutex. We need to do this since we cannot
|
|
|
|
write in a `std::unordered_map` at different hashes concurrently.
|
2024-03-01 14:21:52 -05:00
|
|
|
|
2024-03-01 15:19:52 -05:00
|
|
|
It will automatically grow when the max capacity is reached, though there will
|
2024-03-01 16:30:51 -05:00
|
|
|
be a performance penalty.
|
|
|
|
|
|
|
|
## Performance
|
|
|
|
With a simple stub class and a pool of 10000 objects, using the pool to take a pointer
|
2024-03-02 12:48:49 -05:00
|
|
|
and give it back for each element is significantly faster than doing it by hand.
|
|
|
|
|
2024-03-01 16:30:51 -05:00
|
|
|
```
|
|
|
|
class stub {
|
|
|
|
public:
|
|
|
|
stub() {
|
|
|
|
for (int j{}; j < 1000; j++) { i++; }
|
|
|
|
};
|
|
|
|
void reset() {}
|
|
|
|
|
|
|
|
private:
|
|
|
|
int i = 15;
|
|
|
|
};
|
2024-03-02 12:48:49 -05:00
|
|
|
```
|
|
|
|
```
|
|
|
|
Time (milliseconds) required for allocations without pool: 21
|
|
|
|
Time (milliseconds) required for allocations with pool: 3
|
|
|
|
Time (milliseconds) required for real allocations when constructing pool: 9
|
|
|
|
```
|
|
|
|
|
2024-03-02 13:25:48 -05:00
|
|
|
This trivial example shows some performance improvements that would be much more
|
2024-03-03 00:11:31 -05:00
|
|
|
important should the allocation and construction/destruction of the objects be more
|
|
|
|
complex.
|
2024-03-02 12:48:49 -05:00
|
|
|
|
|
|
|
## Safety
|
|
|
|
AddressSanitizer, LeakSanitizer and ThreadSanitizer have been used to ensure the safety
|
|
|
|
of the class. Tests have been added to ensure the correct behavior in all cases.
|