Alokasi tumpukan kustom

9

Sebagian besar program bisa sangat biasa tentang alokasi tumpukan, bahkan sampai-sampai bahasa pemrograman fungsional lebih suka mengalokasikan objek baru daripada memodifikasi yang lama, dan membiarkan pengumpul sampah khawatir tentang membebaskan barang-barang.

Dalam pemrograman tertanam, sektor hening, ada banyak aplikasi di mana Anda tidak dapat menggunakan alokasi tumpukan sama sekali, karena memori dan kendala real-time yang sulit; jumlah objek dari setiap jenis yang akan ditangani adalah bagian dari spesifikasi, dan semuanya dialokasikan secara statis.

Pemrograman gim (setidaknya dengan gim yang ambisius mendorong perangkat keras) kadang-kadang ada di antaranya: Anda dapat menggunakan alokasi dinamis, tetapi ada cukup memori dan kendala waktu nyata yang lembut sehingga Anda tidak dapat memperlakukan pengalokasi sebagai kotak hitam , apalagi menggunakan pengumpulan sampah, jadi Anda harus menggunakan pengalokasi khusus. Ini adalah salah satu alasan C ++ masih banyak digunakan di industri game; itu memungkinkan Anda melakukan hal-hal seperti http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html

Domain lain apa yang ada di wilayah di antara itu? Di mana, selain dari game, apakah pengalokasi khusus banyak digunakan?

rwallace
sumber
1
Beberapa OS menggunakan pengalokasi slab yang menyediakan caching objek tetapi juga dapat digunakan untuk mengurangi kesalahan cache cache prosesor dengan memetakan anggota suatu objek ke set yang berbeda untuk modulo 2 ** N cache yang diindeks (keduanya dengan memiliki beberapa instance dalam memori yang berdekatan dan oleh variabel padding di dalam slab). Perilaku cache bisa lebih penting daripada alokasi / kecepatan bebas atau penggunaan memori dalam beberapa kasus.
Paul A. Clayton

Jawaban:

4

Setiap kali Anda memiliki aplikasi yang memiliki jalur kritis intensif kinerja, Anda harus memperhatikan bagaimana Anda memperlakukan memori. Sebagian besar aplikasi sisi klien pengguna akhir tidak termasuk dalam kategori ini karena mereka didorong oleh peristiwa utama dan sebagian besar peristiwa berasal dari interaksi dengan pengguna, dan yang tidak memiliki banyak kendala kinerja (jika ada sama sekali).

Namun, banyak perangkat lunak back-end harus memiliki fokus pada bagaimana memori ditangani karena banyak perangkat lunak yang dapat ditingkatkan untuk menangani jumlah klien yang lebih tinggi, jumlah transaksi yang lebih besar, lebih banyak sumber data .... Begitu Anda mulai Mendorong batas, Anda dapat mulai menganalisis bagaimana memori pengguna perangkat lunak Anda dan menulis skema alokasi khusus yang dirancang untuk perangkat lunak Anda daripada mengandalkan pengalokasi memori yang sepenuhnya generik yang ditulis untuk menangani setiap kasus penggunaan yang dapat dibayangkan.

Untuk memberi Anda beberapa contoh ... di perusahaan pertama saya, saya bekerja pada paket Sejarawan, perangkat lunak yang bertanggung jawab untuk mengumpulkan / menyimpan / pengarsipan data kontrol proses (pikirkan pabrik, pembangkit listrik tenaga nuklir atau kilang minyak dengan 10 dari jutaan sensor, kami akan menyimpan data itu). Setiap kali kami menganalisis hambatan kinerja yang mencegah Sejarawan memproses lebih banyak data, sebagian besar masalahnya adalah bagaimana memori ditangani. Kami telah berusaha keras untuk memastikan malloc / free tidak dipanggil kecuali mereka benar-benar diperlukan.

Dalam pekerjaan saya saat ini, saya mengerjakan perekam video digital dan paket analisis pengawasan. Pada 30 fps, setiap saluran menerima bingkai video setiap 33 milidetik. Pada perangkat keras yang kami jual, kami dapat dengan mudah merekam 100 saluran video. Jadi itu kasus lain untuk memastikan bahwa di jalur kritis (panggilan jaringan => tangkap komponen => perangkat lunak manajemen perekam => komponen penyimpanan => disk) tidak ada alokasi memori dinamis. Kami memiliki pengalokasi bingkai khusus, yang berisi ember buffer ukuran tetap dan menggunakan LIFO untuk menggunakan kembali buffer yang sebelumnya dialokasikan. Jika Anda membutuhkan penyimpanan 600Kb, Anda mungkin berakhir dengan buffer 1024Kb, yang membuang-buang ruang, tetapi karena itu dirancang khusus untuk penggunaan kami di mana setiap alokasi sangat berumur pendek, itu bekerja dengan sangat baik karena buffer digunakan,

Dalam jenis aplikasi yang saya jelaskan (memindahkan banyak data dari A ke B dan menangani sejumlah besar permintaan klien) pergi ke tumpukan dan kembali adalah sumber utama kemacetan kinerja CPU. Menjaga tumpukan fragmentasi ke minimum adalah manfaat sekunder, namun sejauh yang saya tahu sebagian besar OS modern sudah menerapkan tumpukan fragmentasi rendah (minimal saya tahu Windows melakukannya, dan saya berharap yang lain juga melakukannya). Secara pribadi, dalam 12+ tahun bekerja di lingkungan seperti ini, saya telah melihat masalah penggunaan CPU yang berhubungan dengan heap cukup sering, sementara tidak pernah sekalipun saya melihat sistem yang sebenarnya menderita heap yang terfragmentasi.

DXM
sumber
"Kami telah berusaha keras untuk memastikan malloc / free tidak dipanggil kecuali mereka benar-benar diperlukan ..." - Saya tahu beberapa orang perangkat keras yang membuat router. Mereka bahkan tidak peduli malloc/free. Mereka memesan blok memori dan menggunakannya sebagai struktur data kursor. Sebagian besar pekerjaan mereka dikurangi untuk melacak indeks.
4

Pemrosesan video, VFX, sistem operasi, dll. Seringkali orang terlalu sering menggunakannya. Struktur data dan pengalokasi tidak perlu dipisahkan untuk mencapai alokasi yang efisien.

Sebagai contoh, ini memperkenalkan banyak kompleksitas tambahan untuk membagi alokasi simpul pohon yang efisien dalam satu oktri dari oktri itu sendiri dan mengandalkan pengalokasi eksternal. Ini tidak selalu merupakan pelanggaran SRP untuk menggabungkan kedua masalah ini bersama-sama dan menjadikannya sebagai tanggung jawab dari peraturan tersebut untuk mengalokasikan banyak node sekaligus secara bersamaan, karena melakukan hal itu tidak menambah jumlah alasan untuk berubah. Secara praktis, ini dapat menurunkannya.

Dalam C ++, misalnya, salah satu efek samping terbelakang dari memiliki wadah standar bergantung pada pengalokasi eksternal telah membuat struktur terkait seperti std::mapdan std::listdianggap hampir tidak berguna oleh komunitas C ++, karena mereka membandingkannya denganstd::allocatorsementara struktur data ini mengalokasikan satu node pada suatu waktu. Tentu saja struktur tertaut Anda akan berkinerja buruk dalam kasus itu, tetapi hal-hal akan menjadi jauh berbeda jika alokasi node yang efisien untuk struktur tertaut dianggap sebagai tanggung jawab struktur data daripada tanggung jawab pengalokasi. Mereka mungkin masih menggunakan alokasi khusus untuk alasan lain seperti pelacakan / profil memori, tetapi mengandalkan pengalokasi untuk membuat struktur tertaut menjadi efisien saat mencoba mengalokasikan node satu per satu membuat semuanya, secara default, sangat tidak efisien, yang akan baik-baik saja jika disertai dengan peringatan terkenal bahwa struktur yang ditautkan sekarang memerlukan pengalokasi khusus, seperti daftar gratis, agar cukup efisien dan menghindari pemicu kesalahan cache kiri dan kanan. Jauh lebih praktis dapat diterapkan mungkin sesuatu seperti itustd::list<T, BlockSize, Alloc>, di mana BlockSizemenunjukkan jumlah node yang berdekatan untuk mengalokasikan sekaligus untuk daftar gratis (menentukan 1 secara efektif akan mengarah std::listseperti sekarang).

Tetapi tidak ada peringatan seperti itu, yang kemudian mengarah ke seluruh komunitas blockheads yang menggemakan mantra kultus yang terkait daftar tidak berguna, misalnya


sumber
3

Area lain di mana Anda mungkin menginginkan pengalokasi kustom adalah untuk mencegah fragmentasi tumpukan . Seiring waktu tumpukan Anda dapat mengalokasikan benda-benda kecil yang terfragmentasi di seluruh tumpukan. Jika program Anda tidak dapat menyimpan memori tumpukan bersama, ketika program Anda mengalokasikan objek yang lebih besar, ia harus mengklaim lebih banyak memori dari sistem karena tidak dapat menemukan blok gratis di antara tumpukan yang ada dan terpecah-pecah (terlalu banyak kecil objek berada di jalan). Total penggunaan memori program Anda akan meningkat dari waktu ke waktu, dan Anda akan mengkonsumsi halaman memori tambahan yang tidak perlu. Jadi ini adalah masalah yang cukup besar untuk program yang diharapkan berjalan dalam jangka waktu yang lama (pikirkan basis data, server, dll.).

Di mana, selain dari game, apakah pengalokasi khusus banyak digunakan?

Facebook

Lihat jemalloc yang mulai digunakan Facebook untuk meningkatkan kinerja tumpukan mereka dan mengurangi fragmentasi.

Doug T.
sumber
Baik. Namun, seorang pengumpul sampah yang menyalin dengan rapi memecahkan masalah fragmentasi, bukan?
rwallace