Apa saja alasan yang sangat bagus untuk std::allocator
mendukung solusi khusus? Sudahkah Anda menghadapi situasi di mana itu benar-benar diperlukan untuk kebenaran, kinerja, skalabilitas, dll? Adakah contoh yang benar-benar pintar?
Pengalokasi khusus selalu menjadi fitur dari Perpustakaan Standar yang belum terlalu saya butuhkan. Saya hanya ingin tahu apakah ada orang di sini di SO dapat memberikan beberapa contoh menarik untuk membenarkan keberadaan mereka.
Satu area di mana pengalokasi kustom dapat bermanfaat adalah pengembangan game, terutama pada konsol game, karena mereka hanya memiliki sedikit memori dan tidak ada swap. Pada sistem seperti itu Anda ingin memastikan bahwa Anda memiliki kontrol ketat atas setiap subsistem, sehingga satu sistem tidak kritis tidak dapat mencuri memori dari yang kritis. Hal-hal lain seperti pengalokasian kumpulan dapat membantu mengurangi fragmentasi memori. Anda dapat menemukan makalah yang panjang dan terperinci tentang topik di:
EASTL - Perpustakaan Template Standar Seni Elektronik
sumber
Saya bekerja pada pengalokasi mmap yang memungkinkan vektor untuk menggunakan memori dari file yang dipetakan memori. Tujuannya adalah untuk memiliki vektor yang menggunakan penyimpanan yang langsung di memori virtual yang dipetakan oleh mmap. Masalah kami adalah meningkatkan pembacaan file yang sangat besar (> 10GB) ke dalam memori tanpa overhead salinan, oleh karena itu saya memerlukan pengalokasi khusus ini.
Sejauh ini saya memiliki kerangka pengalokasi khusus (yang berasal dari std :: pengalokasi), saya pikir itu adalah titik awal yang baik untuk menulis pengalokasi sendiri. Jangan ragu untuk menggunakan kode ini dengan cara apa pun yang Anda inginkan:
Untuk menggunakan ini, nyatakan wadah STL sebagai berikut:
Sebagai contoh, dapat digunakan untuk mencatat kapan saja memori dialokasikan. Apa yang diperlukan adalah struct rebind, atau wadah vektor menggunakan metode alokasi / deallocate superclasses.
Pembaruan: Pengalokasi pemetaan memori sekarang tersedia di https://github.com/johannesthoma/mmap_allocator dan merupakan LGPL. Jangan ragu untuk menggunakannya untuk proyek Anda.
sumber
Saya bekerja dengan mesin penyimpanan MySQL yang menggunakan c ++ untuk kodenya. Kami menggunakan pengalokasi khusus untuk menggunakan sistem memori MySQL daripada bersaing dengan MySQL untuk memori. Hal ini memungkinkan kami untuk memastikan kami menggunakan memori sebagai pengguna yang mengkonfigurasi MySQL untuk digunakan, dan bukan "ekstra".
sumber
Berguna menggunakan pengalokasi khusus untuk menggunakan kumpulan memori alih-alih tumpukan. Itu salah satu contoh di antara banyak lainnya.
Untuk sebagian besar kasus, ini tentu saja merupakan optimasi prematur. Tapi itu bisa sangat berguna dalam konteks tertentu (perangkat tertanam, game, dll).
sumber
Saya belum menulis kode C ++ dengan pengalokasian STL khusus, tetapi saya dapat membayangkan server web yang ditulis dalam C ++, yang menggunakan pengalokasi khusus untuk penghapusan otomatis data sementara yang diperlukan untuk menanggapi permintaan HTTP. Pengalokasi khusus dapat membebaskan semua data sementara sekaligus setelah respons dihasilkan.
Kemungkinan penggunaan lainnya untuk pengalokasi khusus (yang telah saya gunakan) adalah menulis unit test untuk membuktikan bahwa perilaku fungsi tidak tergantung pada beberapa bagian dari inputnya. Pengalokasi khusus dapat mengisi wilayah memori dengan pola apa pun.
sumber
Ketika bekerja dengan GPU atau co-prosesor lain, terkadang bermanfaat untuk mengalokasikan struktur data dalam memori utama dengan cara khusus . Cara khusus ini mengalokasikan memori dapat diimplementasikan dalam pengalokasi kustom dengan cara yang nyaman.
Alasan mengapa alokasi khusus melalui runtime akselerator dapat bermanfaat saat menggunakan akselerator adalah sebagai berikut:
sumber
Saya menggunakan pengalokasi khusus di sini; Anda bahkan mungkin mengatakan itu bekerja mengatasi manajemen memori dinamis kustom lainnya.
Latar Belakang: kami memiliki kelebihan untuk malloc, calloc, gratis, dan berbagai varian operator yang baru dan hapus, dan penghubung dengan senang hati membuat STL menggunakannya untuk kami. Ini memungkinkan kami melakukan hal-hal seperti pengumpulan objek kecil otomatis, deteksi kebocoran, pengalokasian isian, isian gratis, alokasi padding dengan pengawal, penyelarasan garis cache untuk semua dokumen tertentu, dan bebas penundaan.
Masalahnya adalah, kita berjalan di lingkungan yang tertanam - tidak ada cukup memori di sekitar untuk benar-benar melakukan akuntansi deteksi kebocoran dengan benar selama periode yang diperpanjang. Setidaknya, tidak dalam RAM standar - ada tumpukan RAM lain yang tersedia di tempat lain, melalui fungsi alokasi khusus.
Solusi: tulis pengalokasi khusus yang menggunakan tumpukan yang diperluas, dan gunakan hanya di bagian dalam arsitektur pelacakan kebocoran memori ... Segala sesuatu yang lain default ke normal baru / hapus kelebihan yang melakukan pelacakan kebocoran. Ini menghindari pelacakan pelacak itu sendiri (dan juga menyediakan sedikit fungsi pengemasan tambahan, kami tahu ukuran simpul pelacak).
Kami juga menggunakan ini untuk menjaga data profil biaya fungsi, untuk alasan yang sama; menulis entri untuk setiap panggilan fungsi dan kembali, serta sakelar ulir, bisa menjadi mahal dengan cepat. Alokasi kustom lagi memberi kita allocs lebih kecil di area memori debug yang lebih besar.
sumber
Saya menggunakan pengalokasi khusus untuk menghitung jumlah alokasi / alokasi di salah satu bagian dari program saya dan mengukur berapa lama. Ada cara lain yang bisa dicapai tetapi metode ini sangat nyaman bagi saya. Sangat berguna bahwa saya dapat menggunakan pengalokasi khusus hanya untuk sebagian dari wadah saya.
sumber
Satu situasi penting: Ketika menulis kode yang harus bekerja melintasi batas-batas modul (EXE / DLL), penting untuk menjaga alokasi dan penghapusan Anda terjadi hanya dalam satu modul.
Di mana saya bertemu ini adalah arsitektur Plugin di Windows. Sangat penting bahwa, misalnya, jika Anda meneruskan string std :: melintasi batas DLL, bahwa setiap realokasi string terjadi dari tumpukan di mana asalnya, BUKAN tumpukan di DLL yang mungkin berbeda *.
* Ini sebenarnya lebih rumit dari ini, seolah-olah Anda secara dinamis menghubungkan ke CRT, ini mungkin bisa dilakukan. Tetapi jika setiap DLL memiliki tautan statis ke CRT, Anda menuju ke dunia kesakitan, di mana kesalahan alokasi hantu terus terjadi.
sumber
Salah satu contoh waktu saya saya gunakan ini bekerja dengan sistem embedded sangat terbatas sumber daya. Katakanlah Anda memiliki 2k ram gratis dan program Anda harus menggunakan sebagian dari memori itu. Anda perlu menyimpan mengatakan 4-5 urutan di suatu tempat yang tidak ada di tumpukan dan Anda perlu memiliki akses yang sangat tepat di mana hal-hal ini disimpan, ini adalah situasi di mana Anda mungkin ingin menulis pengalokasi Anda sendiri. Implementasi default dapat memecah-mecah memori, ini mungkin tidak dapat diterima jika Anda tidak memiliki cukup memori dan tidak dapat memulai kembali program Anda.
Satu proyek yang sedang saya kerjakan adalah menggunakan AVR-GCC pada beberapa chip berdaya rendah. Kami harus menyimpan 8 urutan panjang variabel tetapi dengan maksimum yang diketahui. Itu penerapan standar perpustakaan dari manajemen memoriadalah pembungkus tipis di sekitar malloc / free yang melacak di mana menempatkan item dengan mendahului setiap blok memori yang dialokasikan dengan pointer untuk hanya melewati ujung memori yang dialokasikan itu. Ketika mengalokasikan sepotong memori baru, pengalokasi standar harus berjalan di masing-masing bagian memori untuk menemukan blok berikutnya yang tersedia di mana ukuran memori yang diminta akan cocok. Pada platform desktop ini akan sangat cepat untuk beberapa item ini tetapi Anda harus ingat bahwa beberapa mikrokontroler ini sangat lambat dan primitif dibandingkan. Selain itu masalah fragmentasi memori adalah masalah besar yang berarti kami benar-benar tidak punya pilihan selain mengambil pendekatan yang berbeda.
Jadi yang kami lakukan adalah menerapkan kumpulan memori kami sendiri . Setiap blok memori cukup besar untuk memenuhi urutan terbesar yang kita butuhkan di dalamnya. Ini mengalokasikan blok memori berukuran tetap sebelumnya dan menandai blok memori mana yang saat ini digunakan. Kami melakukan ini dengan menjaga satu integer 8 bit di mana masing-masing bit mewakili jika blok tertentu digunakan. Kami menukar penggunaan memori di sini karena berusaha membuat seluruh proses lebih cepat, yang dalam kasus kami dibenarkan ketika kami mendorong chip mikrokontroler ini mendekati kapasitas pemrosesan maksimumnya.
Ada beberapa kali saya bisa melihat menulis pengalokasi kustom Anda sendiri dalam konteks sistem embedded, misalnya jika memori untuk urutan tidak dalam ram utama seperti yang sering terjadi pada platform ini .
sumber
Tautan wajib ke pembicaraan CppCon 2015 Andrei Alexandrescu tentang pengalokasi:
https://www.youtube.com/watch?v=LIb3L4vKZ7U
Yang menyenangkan adalah hanya dengan membuat mereka membuat Anda memikirkan ide-ide tentang bagaimana Anda akan menggunakannya :-)
sumber
Untuk memori bersama, sangat penting bahwa tidak hanya kepala wadah, tetapi juga data yang dikandungnya disimpan dalam memori bersama.
Pengalokasi Boost :: Interprocess adalah contoh yang baik. Namun, seperti yang dapat Anda baca di sini , semua ini tidak cukup, untuk membuat semua wadah STL kompatibel dengan memori yang kompatibel (Karena perbedaan pemetaan pemetaan dalam proses yang berbeda, pointer mungkin "pecah").
sumber
Beberapa waktu lalu saya menemukan solusi ini sangat berguna bagi saya: Pengalokasi C ++ 11 yang cepat untuk wadah STL . Ini sedikit mempercepat wadah STL pada VS2017 (~ 5x) serta pada GCC (~ 7x). Ini adalah pengalokasi tujuan khusus berdasarkan kumpulan memori. Ini dapat digunakan dengan wadah STL hanya berkat mekanisme yang Anda minta.
sumber
Saya pribadi menggunakan Loki :: Allocator / SmallObject untuk mengoptimalkan penggunaan memori untuk objek kecil - ini menunjukkan efisiensi yang baik dan kinerja yang memuaskan jika Anda harus bekerja dengan sejumlah kecil benda yang sangat kecil (1 hingga 256 byte). Ini bisa sampai ~ 30 kali lebih efisien daripada standar C ++ alokasi baru / hapus jika kita berbicara tentang mengalokasikan sejumlah kecil objek kecil dengan ukuran berbeda. Juga, ada solusi khusus VC yang disebut "QuickHeap", ini membawa kinerja terbaik (mengalokasikan dan membatalkan alokasi operasi hanya membaca dan menulis alamat blok yang dialokasikan / dikembalikan ke tumpukan, masing-masing hingga 99. (9)% kasus - tergantung pada pengaturan dan inisialisasi), tetapi dengan biaya overhead yang penting - perlu dua petunjuk per luas dan satu tambahan untuk setiap blok memori baru. Itu'
Masalah dengan implementasi standar C ++ baru / hapus adalah bahwa itu biasanya hanya pembungkus untuk alokasi C malloc / gratis, dan itu berfungsi baik untuk blok memori yang lebih besar, seperti 1024+ byte. Ini memiliki overhead yang menonjol dalam hal kinerja dan, kadang-kadang, memori tambahan yang digunakan untuk pemetaan juga. Jadi, dalam kebanyakan kasus, pengalokasi kustom diterapkan dengan cara untuk memaksimalkan kinerja dan / atau meminimalkan jumlah memori tambahan yang diperlukan untuk mengalokasikan objek kecil (≤1024 byte).
sumber
Dalam simulasi grafis, saya telah melihat alokasi kustom digunakan untuk
std::allocator
tidak secara langsung mendukung.sumber