Oyun motorlarında neden custom memory allocator kullanılır? Linear (arena), pool ve stack allocator nasıl çalışır?
Cevap
Genel amaçlı malloc/new her boyuta ve her ömre uyacak şekilde tasarlanır; bu yüzden yavaş olabilir, kilit (lock) alır, fragmentasyon yaratır ve süresi tahmin edilemez. Oyunlar ise ömrü ve boyutu önceden bilinen çok sayıda tahsis yapar; özel allocator'lar bu bilgiyi kullanarak tahsisi neredeyse bedava hale getirir.
| Allocator | Nasıl çalışır | Kullanım |
|---|---|---|
| Linear / Arena | Büyük blok + ilerleyen offset; tek tek free yok, toptan reset | Kare başına geçici veri (frame allocator) |
| Stack | Arena + marker'a geri dönme (LIFO) | Level yükleme, iç içe geçici kapsamlar |
| Pool | Sabit boyutlu slot'lar + free list | Mermi, parçacık, düğüm gibi aynı tipteki nesneler |
| Double-buffered frame | İki arena, kareler arası dönüşümlü | Bir sonraki karede de yaşaması gereken veri |
class FrameArena {
std::byte* base; size_t cap; size_t offset = 0;
public:
FrameArena(size_t size) : base(static_cast<std::byte*>(std::malloc(size))), cap(size) {}
~FrameArena() { std::free(base); }
void* Alloc(size_t size, size_t align = alignof(std::max_align_t)) {
size_t p = (offset + align - 1) & ~(align - 1); // hizalama
if (p + size > cap) return nullptr; // veya assert
offset = p + size;
return base + p;
}
void Reset() { offset = 0; } // her kare sonunda O(1)
};Avantajlar: O(1) tahsis, sıfır fragmentasyon, iyi cache lokalitesi, kolay bellek bütçeleme ve sızıntı takibi.
Dikkat edilecekler:
- Arena'da destructor çağrılmaz; non-trivial nesneler için elle çağırmak gerekir.
- Reset sonrası eski pointer'lar dangling olur.
- Hizalamaya (alignment) uyulmalıdır, aksi halde SIMD tiplerinde crash veya yavaşlama olur.
- Multi-thread için thread-local arena'lar tercih edilir.
Unreal tarafında FMemStack, TInlineAllocator (küçük dizileri stack'te tutar) ve global olarak FMallocBinned bu fikirleri kullanır.
İlgili Unreal & C++ soruları
- Cache-friendly veri yapısı ne demektir? Array of Structs (AoS) ile Struct of Arrays (SoA) farkı nedir?
- C++'ta move semantics nedir? Aşağıdaki kodda hangi constructor'lar çağrılır?
- C++'ta virtual fonksiyonlar ve vtable nasıl çalışır? Destructor neden virtual olmalıdır?
- Unreal'da replication nasıl çalışır? Replicated property, RepNotify ve RPC türleri arasındaki fark nedir?
- Unreal'ın Gameplay Framework'ünde GameMode, GameState, PlayerController, PlayerState ve Pawn'ın rolleri nelerdir?
- TSharedPtr, TUniquePtr, TWeakPtr ve TWeakObjectPtr arasındaki farklar nelerdir?
Bu konuda başka bir soru biliyor musun?
Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.