Oyun geliştirmede kullanılan bellek ayırma modelleri


20

Kendi bellek ayırma yöntemlerimi (bellek havuzu ve profil oluşturma gibi şeyleri destekleyecek) oluşturmayı araştırıyorum, ancak araştırmaya devam ederken bunun oyun geliştirmede nasıl yapıldığını araştırıyorum.

Hangi bellek ayırma tekniğini kullanabilirim ve neden iyi bir teknik?


1
gerçekten ihtiyacın var mı? bir ekibin uygulayabileceği en karmaşık şeylerden sadece bir tanesidir.
Ali1S232

4
Bu benim için bir ilgi alanı, bu yüzden bunu öğrenmek ve uygulamak istiyorum
chadb

Konunun gerçekten ilginç olduğunu söylemeliyim ... Bunun
allot

Modern standart kütüphane malloc'un kaynak kodunu araştırdınız mı, ücretsiz mi yoksa yeni mi ve siliyor musunuz? Soruyorum, çünkü alternatif tahsis stratejilerini algoritmik veya pratik olarak karşılaştırmak için çok yararlı bir temel sağlayacak gibi görünüyor. Ayrıca, içine gireceğiniz şeyle ilgili gerçek bir fikir de sağlayacak gibi görünüyor.
Louis Langholtz

Yanıtlar:


25

Game Engine Mimarisi'nin bu konuyla ilgili bazı bilgileri var. Temel düzey, seviye / kare / vb. Başına bellek gereksinimlerinizi anlamak için bazı analizler yapmanız gerektiğidir. gibidir, ancak yazarın birkaç kez gördüğü birkaç desen vardır:

  • Yığın tabanlı ayırıcılar: Bunlar bir kez büyük bir bellek segmenti tahsis eder ve daha sonra oyunun başka bir yerinden gelen taleplere yanıt olarak o bellek bloğundaki işaretçileri tahsis eder. Bu, bellek ayırma için gereken bağlam anahtarlarından kaçınmak ve ayrıca SIMD işlemleri için sürekliliği veya özel hizalamayı uygulamak için kendi tekniklerinizi kullanabileceğiniz için yararlıdır. Bazı motorlar ayrıca bir tür kaynağın üstten ve diğerinin alttan yüklendiği çift uçlu bir yığın kullanır. Belki de üstten LSR (Load and Stay Resident, oyununuzun tamamı boyunca ihtiyaç duyulacak türden) ve alttan seviye başına veriler.
  • Tek kare bellek veya çift arabelleğe alınmış kare bellek: Bir veya iki kare döngüsü içinde gerçekleşen işlemler için bellek . Bu yararlıdır, çünkü her kareyi ayırmak / yeniden ayırmak yerine, belleği bloğun başlangıcında tutmak için kullandığınız işaretçiyi sıfırlayarak son karenin verilerini uçurabilirsiniz.
  • Nesne Havuzları: Parçacıklar, düşmanlar, mermiler gibi aynı boyuttaki birçok nesne için bir bellek bloğu. Bunlar kullanışlıdır, çünkü havuzunuzda kullanılmayan ilk segmenti bularak kolaylıkla bitişiklik elde edebilirsiniz. Ayrıca yinelemeyi kolaylaştırırlar, çünkü her nesne bir öncekinden bilinen bir ofsettedir.

Yazarın dikkat etmesi gereken en büyük şey bellek parçalanmasıdır. Örneğin, güvenebileceğiniz bir tür bellek disk belleği yedeklemesine sahip olduğunuz bir PC için geliştiriyorsanız, ancak konsol gibi sabit bir bellek bağlamında "bellek yetersiz" olma riski varsa, bu daha az sorun yaratır büyük bir nesneyi ayırmaya çalışırken, hafızanız yalnızca küçük bitişik bloklar mevcut olacak şekilde parçalanır. Bu amaçla, yukarıdaki gibi bir yığın tabanlı ayırıcı da içeriğini periyodik olarak birleştirmek için bir yöntem içermesini tavsiye eder.

Bununla ilgili gerçek kod hakkında daha fazla bilgi için, Christian Gyrling'in "Hafızamız yetersiz mi?" , çoğunlukla bellek kullanım modellerini analiz etme perspektifinden, özel ayırıcılar için teknikleri kapsar, ancak bu aynı zamanda bellek yönetimi için özel bir çözüm tasarlamak için de geçerlidir.


1

Gördüğümden (ama yapmadığımdan) her oyun, tahsis mekanizmalarını bir çerçeveden, bir oyun motorundan, önceki sürümden (2010 -> 2011) devralma eğilimindedir veya özellikle yapı (ya veri yapıları yeniden kullanılabilir ve sabit büyüklükte ya da çok sayıda ve değişken büyüklükte olduğunda).

Ayrıca ses dosyaları / bileşenleri için aynı projedeki seviyelere ve diğer oyun nesnelerine göre farklı ayırıcılarımız vardı. Diğer projelerde, ayırıcılar sadece bu lib tarafından yönetilen bileşenler için harici kütüphanelerden miras alınır.

Optimizasyon gerçekten ihtiyaçlarınıza bağlıdır. Ancak genellikle oyun sahnesine girmeden önce tahsis yapılır ve daha sonra bellek yeniden kullanılır. Bazı oyunlar hiçbir özel ayırıcı kullanmadan kurtulabilir. Ancak, işlemci, bellek ve veri kaynaklarının bütçelendiği aksiyon oyunları için büyük ayırmalarda işlem süresini kaybetmeyi göze alamazsınız, parçalanma ve diğer sorunlara bellek harcayamazsınız.

Örneklerle ilgili olarak, OGRE 3D oyun motoruna bir göz atarak başlamanız gerekir, bellek ayırıcıları yapılandırmak için birkaç seçeneğe sahiptir .


0

Sıklıkla yapılan hata, kendi ayırıcılarınızı yazmaktır, böylece her sistem tarafından ne kadar bellek kullanıldığı üzerinde daha fazla kontrole ve neler olup bittiğine ilişkin daha fazla görünürlük elde edebilirsiniz. Bunu başarmanın çok daha iyi bir yolu bir bellek profili kullanmaktır. Orada çok sayıda bellek profilier var, profilim MemPro bir örnek. Bu, tüm bellek kullanımını takip etmek için tamamen invaziv olmayan bir yoldur ve calltack joker karakter filtrelerini kullanarak otomatik olarak alt sistemlere ayırabilirsiniz. Bellek ayırma ve bellek izleme tamamen ayrı tutmak için en iyisi, tamamen farklı gereksinimleri var.

Hafızanızı havuzlara keyfi olarak bölmek genellikle zararlı olabilir, çünkü her havuzun bir ek yükü olacaktır. Gerçekte farkında olmadan ihtiyacınız olandan çok daha fazla bellek kullanabilirsiniz. İsrafı azaltmak için her şeyi bir araya getirmek her zaman daha iyidir, daha sonra gevşeklik tüm sistem tarafından paylaşılır.

Özel ayırıcıların kullanılmasının tek nedeni CPU performansı (esas olarak önbellek tutarlılığı için) ve parçalanmayı sınırlamaktır. Bunun mükemmel bir örneği bir parçacık sistemidir. Tüm parçacıkların bellekte bitişik olmasını istiyorsunuz ve ana hafızayı çok kısa ömürlü tahsislerle biberlemek istemiyorsunuz. Bölümleme için bir başka iyi örnek de bir betik dilidir.

Genel amaçlı bir malloc değiştirme örneği istiyorsanız, VMem ayırıcıma bir göz atabilirsiniz . Bir dizi sevk edilen AAA oyununda kullanılmıştır. Konsol oyunları için önemli olan parçalanmayı sınırlayan ve bellek ayak izini düşük tutan tekniklere sahiptir. Ayrıca yüksek iplik çekişmesi altında çok hızlı. Web sitemin bu teknikler hakkında kapsamlı belgeleri var.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.