Arena Allocator Tasarımı: Bellek Parçalanmasını Azaltma
Bellek parçalanması (fragmentation) oyunlar ve gerçek zamanlı sistemlerde performans düşürür. Arena allocator bunu çözer: büyük bir bellek bloğu ayırıp içinden lineer şekilde tahsis yaparsınız. Tüm nesneler bitince bloku sıfırlarsınız. Malloc/free gibi karmaşık kitapçılığa gerek yok.
Sorun şu: dinamik tahsis sık yapıldığında bellek yığını dağılır. Boş alanlar çeşitli yerlere dağılınca yeni blok bulmak zorlaşır, CPU cache miss artar. Arena allocator ise önceden büyük bir bölge ayırır, pointer'ı ileri taşır; tahsis O(1) hızında olur.
Pratik örnek: 1000 oyun nesnesi oluşturup siliyorsunuz. Normal malloc/free ile sistem belleği aramaya gider. Arena'da hepsi yan yana tutulur, cache verimli çalışır.
1#include <cstring>2#include <cstdlib>34struct Arena {5char* buffer;6size_t capacity;7size_t offset;8};910Arena arena_create(size_t size) {11return {(char*)malloc(size), size, 0};12}1314void* arena_alloc(Arena* arena, size_t size) {15if (arena->offset + size > arena->capacity) {16return nullptr; // bellek bitti17}18void* ptr = arena->buffer + arena->offset;19arena->offset += size;20return ptr;21}2223void arena_reset(Arena* arena) {24arena->offset = 0;25}2627void arena_destroy(Arena* arena) {28free(arena->buffer);29arena->buffer = nullptr;30}3132struct Entity {33int x, y;34char name[32];35};3637int main() {38Arena arena = arena_create(1024 * 100); // 100 KB3940// 100 entity tahsis et41Entity* entities = (Entity*)arena_alloc(&arena, 100 * sizeof(Entity));4243for (int i = 0; i < 100; i++) {44entities[i].x = i * 10;45entities[i].y = i * 20;46snprintf(entities[i].name, 32, "Entity_%d", i);47}4849printf("100 entity tahsis edildi. Offset: %zu\n", arena.offset);5051// Oyun döngüsü sonu: tümünü sıfırla52arena_reset(&arena);53printf("Arena sıfırlandı. Offset: %zu\n", arena.offset);5455arena_destroy(&arena);56return 0;57}Beklenen çıktı:
1100 entity tahsis edildi. Offset: 64002Arena sıfırlandı. Offset: 0Sık yapılan hata: arena'dan tahsis ettiğiniz belleği manuel free etmeye çalışmak. Arena allocator'ın amacı bu değildir; reset() çağrıncaya kadar bellek tutulur. Eğer ortasında bir nesneyi silmeniz gerekiyorsa, arena allocator uygun değildir, o durumda pool allocator ya da bellek havuzu (memory pool) kullanın.
Arena allocator oyun motorlarında (özellikle frame başında nesne oluşturup frame sonunda temizlemek için) ve veri işleme batch işlemlerinde ideal çözümdür. Bellek süreci tahmin edilebilir, cache-friendly ve hızlı olur.
0 yorum