Bagaimana cara membuat profil dan penyatuan memori per sistem?

8

Saya telah menarik dalam pembuatan profil dan menjaga kumpulan memori terkelola untuk setiap subsistem, sehingga saya bisa mendapatkan statistik tentang berapa banyak memori yang digunakan dalam sesuatu seperti suara atau grafik. Namun, apa yang akan menjadi desain yang berfungsi untuk melakukan ini? Saya berpikir untuk menggunakan banyak pengalokasi dan hanya menggunakan satu per subsistem, bagaimanapun, yang akan menghasilkan variabel global untuk pengalokasi saya (atau begitulah tampaknya bagi saya). Pendekatan lain yang saya lihat / telah disarankan adalah hanya membebani yang baru dan menyerahkan pengalokasi untuk parameter.

Saya punya pertanyaan serupa di stackoverflow di sini dengan hadiah, namun, sepertinya saya mungkin terlalu samar atau tidak ada cukup banyak orang dengan pengetahuan di bidang ini.

chadb
sumber
Menghapus jawaban saya. Saya kembali dan membaca artikel-artikel dan kumpulan-kumpulan yang digunakan untuk melacak alokasi per-sistem bukan bagian dari artikel-artikel itu (meskipun didasarkan pada itu). Jika saya dapat menemukan yang spesifik lagi, saya akan menautkannya! Maaf!
James
1
Lihatlah posting blog ini oleh Jesus de Santos Garcia. Di dalamnya, ia membahas pelacakan memori berdasarkan subsistem, dan menggunakan banyak pengalokasi untuk berbagai kebutuhan memori.
7
Jangan terobsesi dengan paradigma teoretis. Jika Anda membutuhkan fungsionalitas dan data secara global, maka tidak ada yang salah dengan global. Sudah ada banyak fungsi global seperti baru / delete / malloc / gratis. Cukup tambahkan apa yang harus Anda lakukan, untuk menyelesaikan pekerjaan.
Maik Semder

Jawaban:

1

Pasti pertanyaan yang mungkin terdengar samar bagi sebagian orang;)

Tapi saya rasa saya tahu dari mana Anda berasal.

Anda memiliki sejuta pilihan untuk bagaimana Anda dapat memilih untuk mengimplementasikan ini. Beberapa dari pilihan itu harus berkisar pada platform target dan tujuan desain keseluruhan. Pertimbangan itu akan memutus ikatan apa pun, sampai Anda merasa cukup nyaman dengan biaya implementasi yang berbeda cukup untuk menumbuhkan desain dari platform dan keprihatinan desain umum terlebih dahulu. Jadi sampai saat itu, berikut adalah beberapa cara yang tidak akan dikenakan biaya dalam hal kompleksitas (beban manajemen) atau dalam berurusan dengan penghapusan atau perubahan jika Anda berubah pikiran ...

Jika tujuannya adalah untuk mengukur dan mengalokasikan, dengan kemungkinan menggunakan kumpulan, maka Anda harus berpikir terlebih dahulu tentang set minimum kode layak huni untuk memulai. Demi penjelasan, jika Anda sebagian ke kelas, Anda bisa membuat satu kelas, yang membiarkan berdiri untuk tumpukan, atau sebaliknya menggunakan satu set fungsi yang mengambil pegangan atau nama tumpukan. Ini benar-benar masalah semantik jujur. Keputusan selanjutnya adalah baru atau malloc; Saya sebagian ke malloc karena berkali-kali saya berurusan dengan konstruksi tingkat rendah dan saya tahu di sebagian besar implementasi bahwa panggilan baru malloc, dan saya tidak perlu khawatir tentang kompleksitas kelebihan beban baru, dan khawatir tentang itu di semua platform . Namun saya telah berkali-kali membangun sistem atau komponen di sekitar overloading atau hooking baru. Dan tentu saja masalah atau perbedaan inti, apakah itu 'baru' harus tahu tipe sebelum alokasi, di mana 'malloc' tidak peduli dan dengan malloc Anda memutuskan untuk mengetik setelah alokasi. Semua detail itu untuk memberi Anda ide dan konteks untuk membuat keputusan desain dalam hal-hal seperti ini :)

Jadi saya akan memilih kelas dan malloc, karena lebih mudah dijelaskan di sini, tetapi pada akhirnya tidak masalah. Bagian dalam akan berakhir dengan sedikit perbedaan material dibandingkan dengan keseluruhan desain keseluruhan.

Jadi dalam hipotesis ini, saya tahu bahwa (atau akan menganggap itu) saya mungkin berakhir dengan 7-8 instantiations kelas sub-sistem nyata, dan mengantisipasi 100-an ribu panggilan untuk alokasi dan gratis. Karena banyak keingintahuan saya dan dorongan nyata dalam semua ini, sebenarnya tentang ukuran dan sisi profil, saya tidak ingin membebani kinerja aplikasi secara bijaksana. Sebagai permulaan, saya mungkin memutuskan untuk membiarkan semuanya terbuka dan terbuka sampai saya menyelesaikannya, saat saya berjalan menerapkannya di seluruh aplikasi; struct akan melakukan ini dengan baik. 'S_' adalah untuk menunjukkan vars mana yang secara jelas dimaksudkan untuk statistik.

struct Mem
{
  int s_allocs;
  int s_frees;
  int s_peak;
  int s_current;
  void* heap; // if you wanted to go into having real actual separate heaps, else ignore
  void* alloc(int size);
  void free(void* p);

  Mem() {memset(this,0,szieof(Mem));}  // want this to be inlined with the call site constructor (a design decision example)
}

class MySubSystem
{
   Mem mem;
   ....  you get the idea
}

Ini sangatringan di banyak bidang, dan mungkin tempat yang bagus untuk mulai menyempurnakan kemana pun Anda benar-benar ingin melakukannya. Dan Anda langsung memiliki masalah, bagaimana Anda tahu ukuran barang yang dibebaskan. (Ini akan menjadi masalah yang harus dipecahkan untuk hampir semua pendekatan.) Karena ini adalah forum permainan, Anda dapat mempertimbangkan doping beberapa byte pertama dengan ukuran, atau Anda harus membungkus atau mengingat dengan cara lain. Sebagian besar kepekaan dev gim seharusnya tidak terlalu menentang doping, dan ini contoh paling sederhana, mengingat saya sudah membuat dinding teks. Pada dasarnya seperti ini: Anda tidak ingin jika dapat membantu menghancurkan penyelarasan yang melekat, Anda ingin tahu, karena hampir gratis, jika ukurannya koheren. Jadi sesuatu yang sesederhana "s_allocs ++; s_total + = size; uint64 * p = (uint64 *) malloc / calloc (size + = 8); * p = 0xDEADDAED00000000 | ukuran; mengembalikan p + 1; "di mana alokasi akan kurang dari 4GB, dan uint64 adalah apa pun yang menurut kompiler adalah int 64 bit yang tidak ditandatangani, dan di mana Anda dapat memeriksa nilai kewarasan secara gratis.

Ini semua adalah satu cara untuk memberi Anda jumlah minimum dengan biaya minimum yang memenuhi persyaratan. Itu tidak tidakalamat kelas pengalokasian yang memiliki fungsi virtual jika mereka berada dalam ruang lingkup untuk profiling atau manajemen, karena Anda tidak dapat mengantisipasi ukuran lingkungan c ++ yang Anda gunakan untuk kebutuhan tersebut tanpa membebani atau mengaitkan yang baru, atau jika Anda mengandalkan konstruktor di salah satu cara aneh yang tidak bisa ditangani oleh fungsi 'init' lainnya. Kalau tidak, sebuah stuct adalah kelas adalah alokasi yang sewenang-wenang dan semua sama, ketika Anda melemparkan. Jika Anda tidak menyukai yang baru dan membutuhkan tabel virtual atau semantik konstruktor yang melekat, maka Anda harus mengaitkan yang baru, tetapi itu adalah binatang 'nother', yang harus Anda pelajari untuk memastikan Anda melakukan apa yang perlu baru dan harus memberi sinyal kode Anda sedang menangani yang baru, di mana ember ini diterapkan. Tetapi sebaliknya konsep di atas sama.

Lebih penting lagi, ini akan membuat otak Anda maju, dan semoga sejalan dengan apa yang Anda butuhkan dan apa toleransi Anda, sekarang setelah Anda melihat sedikit di balik tirai. Tidak ada penyihir :)

Ceroboh
sumber
Jika Anda menggunakan fungsi templat untuk mengalokasikan dan membebaskan itu seharusnya tidak menjadi masalah untuk menentukan ukuran yang dibutuhkan untuk dibebaskan (dan dialokasikan).
API-Beast
1
Intinya adalah untuk menunjukkan masalah yang mendasarinya untuk membantu memberikan dasar untuk memilih abstraksi apa pun, bukan untuk menyajikan abstraksi tertentu. Semuanya memiliki kompromi. Pengetahuan ukuran tidak perlu untuk melakukan akta pembebasan, tetapi untuk statistik.
Celess
1

Anda tidak perlu mengimplementasikan apa pun di game Anda untuk data ini. Alat-alat seperti Massif Valgrind dapat mengekstraksi semua data yang diperlukan dari Simbol Debug. Anda dapat melihat kesedihan Massif di Massif Visualizer .

API-Beast
sumber
4
Saya kira kebanyakan game grafis tidak akan dikembangkan pada sistem yang menjalankan Valgrind, sayangnya.
Kylotan
1

Saya sangat menyarankan untuk tidak menulis alokasi memori Anda sendiri. Anda memerlukan yang stabil, andal dan teruji, dengan fungsionalitas debug yang baik seperti deteksi korupsi dan yang paling penting: dengan statistik yang andal. Ini bukan tugas yang mudah dan memiliki banyak jebakan. Ada yang bagus dan mudah digunakan di luar sana, misalnya:

Doug Lea Allocator

Muncul dengan konsep ruang memori, Anda dapat menggunakan satu per subsistem. Ini sangat dioptimalkan dan memberi Anda statistik dan informasi runtime yang hebat.

Maik Semder
sumber