nlib
heap/cachedheap/cachedheap.cpp

nn::nlib::CachedHeap, nn::nlib::CentralHeapを明示的に利用してメモリの確保と解放を行います。

nmalloc/nfreeを利用した場合、間接的にこれらのクラスを利用することになりますが、明示的に利用することも可能です。 このサンプルはその利用方法を説明しています。

nmalloc経由で利用するのではなく明示的に利用することにより、プロセス全体でCentralHeapを共有するのではなく、モジュール別にCentralHeapを複数利用したり、単一スレッド内でCachedHeapを複数利用したりすることが可能になります。

using ::nlib_ns::threading::Thread;
using ::nlib_ns::heap::CentralHeap;
using ::nlib_ns::heap::CachedHeap;
const size_t heapmem_size = 1024 * 512;
NLIB_ALIGNAS(4096) static char heapmem[heapmem_size];
// All the threads allocates memory via CachedHeap from CentralHeap.
CentralHeap g_CentralHeap;
class HeapSetup {
public:
HeapSetup() {
g_CentralHeap.Initialize(&heapmem[0], heapmem_size, 0);
}
~HeapSetup() {
g_CentralHeap.Finalize();
}
};
volatile bool g_Success = true;
static void ThreadFunc(void* ptr) {
NLIB_UNUSED(ptr);
// Initializes CachedHeap, and associate it with the Central Heap.
// There needs a CachedHeap object per a thread.
CachedHeap heap;
if (!g_CentralHeap.MakeCache(&heap)) {
g_Success = false;
return;
}
const int n = 1000;
void* p[n];
for (int j = 0; j < 1000; ++j) {
for (int i = 0; i < n; ++i) {
// Allocation is fast if free memory is cached in CachedHeap,
// because there needs no mutex to be acquired.
p[i] = heap.Alloc(8);
if (!p[i]) g_Success = false;
}
for (int i = 0; i < n; ++i) {
// Freed small memory is cached in CachedHeap.
// The amount of the cache memory is controlled,
// and it returns the memory to CentralHeap when it grows too big.
heap.Free(p[i]);
}
}
// In the destructor of CachedHeap, the memory cached is returned to CentralHeap.
}
const int kNumThread = 10;
Thread th[kNumThread];
static bool SampleMain(int, char**) {
HeapSetup obj;
{
uint64_t from, to;
from = GetTickTime();
for (int i = 0; i < kNumThread; ++i) {
th[i].StartRaw(ThreadFunc, NULL);
}
for (int i = 0; i < kNumThread; ++i) {
th[i].Join();
}
to = GetTickTime();
nlib_printf("Small: using CachedHeap: %" PRIu64 " msec\n", to - from);
}
return g_Success;
}
NLIB_MAINFUNC