Semua program yang saya lihat mengatur memori data mereka ke dalam satu atau lebih tumpukan panggilan (biasanya ukuran tetap, tetapi kadang-kadang tidak), tumpukan, dan memori statis. Akhir-akhir ini penyimpanan statis thread-lokal telah ditambahkan ke ini juga.
Pernahkah ada upaya untuk mengatur tata letak memori data dengan cara yang sangat berbeda, misalnya tanpa tumpukan panggilan? Atau mengatur memori dengan cara berbeda yang menghasilkan hal yang sama?
Jawaban:
Anda mungkin ingin melangkah mundur dan melihat dari mana dan mengapa model-model yang ada berasal. Ketika suatu proses dibuat, itu hanya diberi area penyimpanan datar yang hanya diindeks dari 0 ke N. Karena area penyimpanan ini (berbicara tentang RAM di sini) didukung oleh perangkat keras khusus dan beberapa semikonduktor mewah itu terjadi cukup cepat, tapi itu bukan satu-satunya dari jenisnya. Perangkat lain seperti hard drive pada dasarnya adalah hal yang sama, ruang datar dialamatkan oleh indeks, tetapi banyak pesanan lebih lambat.
Alasan mengapa "tumpukan" ada adalah karena tidak praktis untuk setiap aplikasi untuk mencoba mengelola penggunaan RAM dengan sendirinya. Kembali ke masa lalu, itulah tepatnya yang terjadi, para programmer merencanakan sebelumnya persis seperti apa setiap lokasi RAM akan digunakan. Ketika perangkat lunak menjadi lebih kompleks, kata seseorang, bukankah menyenangkan jika saya bisa pergi ke kotak hitam dan mengatakan "Saya butuh 10 byte, jadi beri aku" dan tidak perlu khawatir tentang semua detail rumit di mana dan bagaimana 10 byte itu berasal dari atau bagaimana mereka direklamasi. Itulah yang tumpukan, tidak benar-benar mendapatkan lebih mendasar daripada itu.
Setiap kali sebuah thread dibuat, ada beberapa struktur data (dan stack), yang diperoleh dengan menggunakan "operasi beri" yang sama seperti yang saya jelaskan. Tumpukan yang biasa digunakan secara universal karena sangat cocok dengan frame panggilan fungsi panggil dan sifat LIFO-nya. Secara teori, setiap pemanggilan fungsi dan variabel lokal dapat dialokasikan pada heap, tetapi itu akan terlalu mahal, dibandingkan dengan hanya beberapa instruksi perakitan yang diperlukan untuk memperbarui register stack pointer (ESP pada x86).
Penyimpanan lokal utas (TLS) juga dibangun di atas tumpukan. Ketika utas dibuat, sebagai bagian dari perjalanan ke tumpukan untuk mengalokasikan memori untuk struktur manajemen, ruang terpisah untuk TLS juga dialokasikan dari tumpukan.
Jadi pada akhirnya, semua yang Anda miliki adalah pengalokasi memori generik (yaitu heap) dan yang lainnya adalah formulir khusus. Dengan kata lain, jika Anda bersedia memberikan beberapa aspek "Saya ingin mengalokasikan sebanyak (atau sesedikit) yang saya inginkan, simpan selama yang saya inginkan dan gratis kapan pun saya mau", Anda bisa pergi berdagang off pengalokasian penumpukan generik untuk model lain yang menawarkan kecepatan tetapi dengan biaya beberapa batasan lainnya.
Ambil tumpukan. Ini sangat cepat bila dibandingkan dengan heap, tetapi dua trade off adalah 1) Anda tidak mengontrol ketika memori dibebaskan; alih-alih begitu fungsi keluar, apa pun yang Anda alokasikan hilang dan 2) karena ukuran tumpukan pada umumnya terbatas, Anda harus berhati-hati mengalokasikan sejumlah besar data secara langsung pada tumpukan.
Tipe lain dari "model memori" adalah Virtual Memory Manager (VMM) yang ditawarkan oleh hampir semua OS utama melalui panggilan sistem. VMM sangat mirip dengan tumpukan dalam arti bahwa Anda dapat meminta sejumlah memori dan menyimpannya selama yang Anda inginkan. Namun, batasannya adalah Anda hanya dapat mengalokasikan memori dalam kelipatan ukuran halaman (misalnya 4KB) sehingga menggunakan VMM secara langsung akan menyebabkan banyak overhead dalam aplikasi tipikal yang sering mengalokasikan 8-24 byte pada satu waktu. Faktanya, hampir setiap implementasi heap dibangun di atas VMM khusus untuk tujuan memungkinkan alokasi blok- kecil yang sangat generik, tidak khusus . Heap pergi ke VMM setiap kali membutuhkan lebih banyak memori dan kemudian membagikan banyak potongan kecil dari memori itu ke aplikasi.
Jika Anda memiliki aplikasi, yang memiliki kebutuhan untuk mengalokasikan blok besar, Anda dapat mempertimbangkan untuk langsung pergi ke VMM, meskipun beberapa tumpukan memiliki if-statement di dalam malloc () dan jika ukuran blok lebih besar dari beberapa ambang batas, mereka hanya pergi ke VMM untukmu.
Bentuk lain dari pengalokasian bukannya langsung menggunakan tumpukan, akan menjadi kumpulan. Kumpulan adalah pengalokasi khusus di mana semua blok memiliki ukuran yang sama. Kolam (seperti tumpukan dan TLS) dibangun di atas tumpukan atau VMM. Kolam berguna di tempat-tempat di mana Anda mengalokasikan banyak (jutaan) objek kecil berumur pendek dengan ukuran yang sama. Pikirkan layanan jaringan yang memproses permintaan masuk. Setiap permintaan klien dapat menghasilkan struktur byte N yang sama yang dialokasikan untuk menangani permintaan itu. Yang menarik dari menggunakan kumpulan adalah bahwa setiap kumpulan hanya menangani satu ukuran blok (tetapi Anda dapat membuat beberapa kumpulan). Keuntungan dari kolam adalah bahwa karena semua benda berukuran sama, tidak memerlukan logika yang rumit. Sebaliknya, setiap kali Anda membutuhkan blok baru, itu hanya memberi Anda blok yang baru saja dibebaskan.
Dan terakhir, ingat bahwa hard drive yang saya sebutkan di bagian atas. Anda bisa memiliki model memori yang berperilaku seperti sistem file dan menduplikasi ide yang sama dari entri direktori dan node-i untuk memungkinkan Anda alokasi hierarki blok data di mana masing-masing blok data sesuai dengan jalur. Itulah yang dilakukan tmpfs .
Di luar hal-hal yang saya sebutkan, saya yakin ada model yang lebih khusus, tetapi pada akhirnya karena semuanya didasarkan pada ruang alamat datar (yaitu sampai beberapa genuis datang dengan semacam aneh-ruang $$ non-datar ), semuanya kembali ke pengalokasi "gimme" generik yang bisa berupa VMM atau heap.
sumber
Satu-satunya kasus yang dapat saya pikirkan adalah perangkat keras khusus di mana Anda mungkin memiliki semuanya berjalan di lokasi tetap dalam memori. Hampir semua yang ada dalam model memori saat ini diperlukan jika Anda menginginkan program yang sepenuhnya fleksibel.
Tanpa tumpukan Anda tidak dapat memiliki variabel lokal, tumpukan panggilan, dll. Apa pun yang Anda tulis untuk mengimplementasikan yang akan berakhir sangat mirip dengan tumpukan.
Memori statis dan tumpukan yang berpotensi Anda jatuhkan untuk aplikasi tertentu, tetapi sekali lagi Anda akan membutuhkannya kembali dalam beberapa bentuk atau lainnya untuk melakukan sesuatu yang lebih maju.
Jadi apapun yang Anda ciptakan untuk mengganti salah satu dari ketiganya akan berakhir sangat mirip salah satu dari ketiganya pada akhirnya ...
Untuk mendekatinya dari sudut yang lain, apa yang mungkin Anda tambahkan yang baru? Anda dapat berpotensi memperdebatkan hal-hal seperti prosesor grafis / fisika / cache cpu / etc adalah lokasi memori baru, tetapi sebenarnya itu hanyalah contoh terpisah atau cara mempercepat akses ke model yang ada.
... jadi sampai seseorang muncul dengan lompatan konseptual raksasa semacam itu, saya pikir kita tidak akan melihat perubahan besar di area ini untuk waktu yang lama ...
sumber