Pola alokasi memori digunakan dalam pengembangan game

20

Saya telah meneliti membuat metode pengalokasian saya sendiri (yang akan mendukung hal-hal seperti kumpulan memori dan profil), namun, ketika saya melanjutkan penelitian saya, saya telah mencari bagaimana hal ini dilakukan dalam pengembangan game.

Apa teknik alokasi memori yang bisa saya gunakan, dan mengapa itu teknik yang baik?

chadb
sumber
1
apakah Anda benar-benar perlu? itu hanya salah satu hal paling rumit yang bisa diterapkan tim, jika mereka bisa menerapkannya.
Ali1S232
4
Ini adalah bidang yang menarik bagi saya, jadi saya ingin mempelajarinya dan mengimplementasikannya
chadb
Saya harus mengatakan bahwa subjeknya benar-benar menarik ... Ada kasus-kasus di mana itu bisa berarti membagikan, tetapi pada Anda rata-rata game PC saya lebih suka khawatir tentang game yang sebenarnya ...
rioki
Sudahkah Anda meneliti kode sumber untuk malloc perpustakaan standar modern dan gratis atau baru dan menghapus? Saya bertanya karena tampaknya itu akan memberikan dasar yang sangat berguna untuk membandingkan strategi alokasi alternatif terhadap algoritma atau praktis. Tampaknya itu juga akan memberikan beberapa wawasan nyata tentang apa yang akan Anda hadapi.
Louis Langholtz

Jawaban:

25

Arsitektur Mesin Game memiliki beberapa informasi mengenai topik ini. Dasar-dasarnya adalah bahwa Anda perlu melakukan beberapa analisis untuk memahami apa kebutuhan memori Anda per level / bingkai / dll. seperti, tetapi ada beberapa pola yang penulis sebutkan telah melihat beberapa kali:

  • Alokasi berbasis tumpukan: Ini mengalokasikan sebagian besar memori sekali, dan kemudian mengalokasikan pointer dalam blok memori itu sebagai tanggapan terhadap permintaan dari tempat lain dalam permainan. Ini berguna untuk menghindari sakelar konteks yang diperlukan oleh alokasi memori, dan juga karena Anda dapat menggunakan teknik Anda sendiri untuk menegakkan kedekatan, atau perataan khusus untuk operasi SIMD. Beberapa mesin juga menggunakan tumpukan ujung ganda di mana satu jenis sumber daya dimuat dari atas dan yang lainnya diambil dari bawah. Mungkin LSR (Load and Stay Resident, jenis hal yang akan dibutuhkan di seluruh permainan Anda) dari atas, dan data per-level dari bawah.
  • Memori bingkai tunggal, atau memori bingkai buffer ganda: Memori untuk operasi yang terjadi dalam satu atau dua siklus frame. Ini berguna karena alih-alih harus mengalokasikan / membatalkan alokasi setiap frame, Anda dapat membuang data frame terakhir dengan mengatur ulang pointer yang Anda gunakan untuk melacak memori ke awal blok.
  • Object Pools: Blok memori untuk banyak objek berukuran sama, seperti partikel, musuh, proyektil. Ini berguna karena Anda dapat dengan mudah mencapai kedekatan dengan menemukan segmen pertama yang tidak digunakan di kumpulan Anda. Mereka juga membuat iterasi mudah, karena masing-masing objek diketahui offset dari yang terakhir.

Hal terbesar yang penulis sebutkan untuk diperhatikan adalah fragmentasi memori. Ini bukan masalah jika Anda mengembangkan misalnya PC di mana Anda memiliki semacam cadangan paging memori yang dapat Anda andalkan, tetapi dalam konteks memori tetap seperti konsol, ada risiko "kehabisan memori" ketika mencoba mengalokasikan untuk objek besar karena memori Anda terfragmentasi sedemikian rupa sehingga hanya blok kecil yang berdekatan yang tersedia. Untuk itu, ia merekomendasikan bahwa pengalokasi berbasis stack seperti di atas juga termasuk metode defragmenting isinya secara berkala.

Untuk informasi lebih lanjut tentang kode aktual yang terlibat dalam hal ini, saya sangat merekomendasikan artikel Christian Gyrling, "Apakah kita kehabisan memori?" , yang mencakup teknik untuk pengalokasi khusus, sebagian besar dari perspektif menganalisis pola penggunaan memori, tetapi ini juga berlaku untuk merancang solusi khusus untuk manajemen memori.


sumber
1

Dari apa yang saya lihat (tetapi tidak dilakukan), setiap game cenderung mewarisi mekanisme alokasi dari suatu kerangka kerja, dari mesin game, dari versi sebelumnya (2010 -> 2011) atau mendapat seperangkat yang baru yang ditulis khusus untuk struktur (baik ketika struktur data dapat digunakan kembali dan dengan ukuran tetap atau berbagai jenis dan ukuran variabel).

Kami juga memiliki pengalokasi yang berbeda untuk file / komponen suara daripada untuk level dan objek game lainnya dalam proyek yang sama. Di proyek lain, pengalokasi diwarisi dari perpustakaan eksternal hanya untuk komponen yang dikelola oleh lib itu.

Optimalisasi sangat tergantung pada kebutuhan Anda. Tetapi biasanya alokasi dilakukan sebelum memasuki adegan permainan dan kemudian memori digunakan kembali. Beberapa game bisa lolos tanpa mendapat alokasi kustom. Tetapi untuk game aksi di mana prosesor, memori, dan sumber daya data dianggarkan Anda tidak mampu kehilangan waktu pemrosesan pada alokasi besar, Anda tidak dapat membuang memori untuk fragmentasi dan masalah lainnya.

Mengenai contoh, Anda harus mulai dengan melihat mesin game OGRE 3D yang memiliki beberapa opsi untuk mengkonfigurasi pengalokasi memori.

Anjing hutan
sumber
0

Kesalahan yang sering dilakukan adalah menulis pengalokasi Anda sendiri sehingga Anda dapat lebih mengontrol berapa banyak memori yang digunakan oleh setiap sistem dan memiliki lebih banyak visibilitas pada apa yang sedang terjadi. Cara yang jauh lebih baik untuk mencapai ini adalah dengan menggunakan profiler memori. Ada banyak profiler memori di luar sana, profiler saya MemPro menjadi salah satu contoh. Ini adalah cara yang sepenuhnya non-invasif untuk melacak semua penggunaan memori, dan Anda dapat secara otomatis memecahnya menjadi sub sistem menggunakan filter wildcard callstack. Idealnya yang terbaik untuk menjaga alokasi memori Anda dan pelacakan memori benar-benar terpisah, mereka memiliki persyaratan yang sama sekali berbeda.

Membagi memori Anda secara sewenang-wenang ke dalam kumpulan sering dapat merugikan karena setiap kumpulan akan memiliki overhead. Anda dapat menggunakan lebih banyak memori daripada yang Anda butuhkan tanpa benar-benar menyadarinya. Untuk mengurangi pemborosan, selalu lebih baik untuk menyatukan semuanya, slack kemudian dibagi oleh seluruh sistem.

Satu-satunya alasan untuk menggunakan pengalokasi khusus adalah kinerja CPU (terutama untuk koherensi cache) dan untuk membatasi fragmentasi. Contoh sempurna dari ini adalah sistem partikel. Anda ingin semua partikel bersebelahan dalam memori dan Anda tidak ingin menambahkan memori utama dengan banyak alokasi berumur pendek. Contoh bagus lain untuk mempartisi adalah bahasa scripting.

Jika Anda ingin contoh pengganti malloc tujuan umum, Anda dapat melihat pengalokasi VMem saya . Ini telah digunakan di sejumlah game AAA yang dikirim. Ini memiliki teknik yang membatasi fragmentasi dan menjaga jejak memori rendah, sesuatu yang penting untuk konsol game. Ini juga sangat cepat di bawah pertentangan thread tinggi. Situs web saya memiliki dokumentasi yang luas tentang teknik-teknik ini.

Stewart Lynch
sumber