GNU/Linux >> Belajar Linux >  >> Linux

mmap:apakah file yang dipetakan akan segera dimuat ke memori?

Ya, mmap membuat pemetaan. Itu biasanya tidak membaca seluruh konten dari apa pun yang telah Anda petakan ke dalam memori. Jika Anda ingin melakukannya, Anda dapat menggunakan panggilan sistem mlock/mlockall untuk memaksa kernel membaca konten pemetaan ke dalam RAM, jika berlaku.


Tidak, ya, mungkin. Itu tergantung.

Memanggil mmap umumnya hanya berarti bahwa untuk aplikasi Anda, konten file yang dipetakan dipetakan ke ruang alamatnya seolah-olah file itu dimuat di sana. Atau, seolah-olah file tersebut benar-benar ada di memori, seolah-olah file tersebut satu dan sama (termasuk perubahan yang ditulis kembali ke disk, dengan asumsi Anda memiliki akses tulis).

Tidak lebih, tidak kurang. Tidak ada gagasan memuat sesuatu, aplikasi juga tidak tahu apa artinya ini.

Aplikasi tidak benar-benar memiliki pengetahuan tentang hal seperti memori, meskipun sistem memori virtual membuatnya tampak seperti itu. Memori yang dapat "dilihat" (dan diakses) oleh aplikasi mungkin atau mungkin tidak sesuai dengan memori fisik yang sebenarnya, dan ini pada prinsipnya dapat berubah kapan saja, tanpa peringatan sebelumnya, dan tanpa alasan yang jelas (jelas untuk aplikasi Anda).
Selain kemungkinan mengalami penundaan kecil karena kesalahan halaman, sebuah aplikasi (pada prinsipnya) sama sekali tidak mengetahui hal semacam itu terjadi dan memiliki sedikit atau tidak ada kendali atasnya.

Aplikasi akan, secara umum, memuat halaman dari file yang dipetakan (termasuk yang dapat dieksekusi utama!) sesuai permintaan, sebagai konsekuensi menghadapi kesalahan. Namun, sistem operasi biasanya akan mencoba melakukan prefetch data secara spekulatif untuk mengoptimalkan performa.

Dalam praktiknya, memanggil mmap akan segera dimulai untuk (secara asinkron) mengambil halaman dari awal pemetaan, hingga ukuran tertentu yang ditentukan implementasi. Artinya, pada prinsipnya, untuk file kecil jawabannya adalah "ya", dan untuk file yang lebih besar jawabannya adalah "tidak".
Namun, mmap tidak memblokir untuk menunggu penyelesaian readahead, yang berarti Anda tidak memiliki jaminan bahwa file apa pun ada di RAM segera setelah mmap pengembalian (bukan berarti Anda memiliki jaminan itu kapan saja!). Sejauh ini, jawabannya adalah "mungkin".

Di Linux, terakhir kali saya melihat, ukuran prefetch default adalah 31 blok (~127k) -- tetapi ini mungkin telah berubah, plus ini adalah parameter yang dapat disetel. Saat halaman di dekat atau di akhir area yang diambil sebelumnya disentuh, lebih banyak halaman diambil secara asinkron.
Jika sudah mengisyaratkan MADV_RANDOM ke madvise , prefetching "kurang mungkin terjadi", di Linux ini sepenuhnya menonaktifkan prefetch.

Sebaliknya, memberikan MADV_SEQUENTIAL petunjuk akan mengambil secara asinkron "lebih agresif" mulai dari awal pemetaan (dan dapat membuang halaman yang diakses lebih cepat). Di Linux, "lebih agresif" berarti dua kali jumlah normal.

Memberikan MADV_WILLNEED petunjuk menyarankan (tetapi tidak menjamin) bahwa semua halaman dalam rentang tertentu dimuat sesegera mungkin (karena Anda mengatakan akan mengaksesnya). OS mungkin mengabaikan ini, tetapi di Linux, ini diperlakukan lebih sebagai perintah daripada petunjuk, hingga batas RSS maksimum proses, dan batas yang ditentukan implementasi (jika saya ingat dengan benar, 1/2 jumlah RAM fisik ).
Perhatikan bahwa MADV_DONTNEED bisa dibilang diimplementasikan secara salah di Linux. Petunjuk tidak ditafsirkan dengan cara yang ditentukan oleh POSIX, yaitu Anda baik-baik saja dengan halaman yang sedang keluar halaman untuk saat ini, tetapi Anda bermaksud membuangnya . Yang tidak membuat perbedaan besar untuk halaman yang dipetakan hanya-baca (selain penundaan kecil, yang menurut Anda tidak apa-apa), tetapi tentu saja bermakna untuk yang lainnya.
Secara khusus, menggunakan MADV_DONTNEED berpikir Linux akan merilis halaman yang tidak dibutuhkan setelah OS menulisnya dengan malas ke disk bukan cara kerjanya ! Anda harus menyinkronkan secara eksplisit, atau mempersiapkan kejutan.

Setelah memanggil readahead pada deskriptor file sebelum memanggil mmap (atau alternatifnya, setelah membaca/menulis file sebelumnya), isi file akan dalam praktek memang berada di RAM segera.
Namun, ini hanyalah detail implementasi (sistem memori virtual terpadu), dan tunduk pada tekanan memori pada sistem.

Memanggil mlock akan - dengan asumsi berhasil - segera memuat halaman yang diminta ke dalam RAM. Itu memblokir sampai semua halaman ada secara fisik, dan Anda memiliki jaminan bahwa halaman tersebut akan tetap berada di RAM sampai Anda membukanya.

Ada fungsionalitas untuk kueri (mincore ) apakah salah satu atau semua halaman dalam rentang tertentu benar-benar ada pada saat itu juga, dan berfungsi untuk memberikan petunjuk kepada OS tentang apa yang Anda inginkan untuk melihat kejadian tanpa jaminan keras (madvise ), dan akhirnya fungsionalitas untuk memaksa subkumpulan laman yang terbatas untuk hadir di memori (mlock ) untuk proses istimewa.

Mungkin tidak, baik karena kurangnya hak istimewa maupun karena melebihi kuota atau jumlah RAM fisik yang ada.


Secara default, mmap() hanya mengonfigurasi pemetaan dan pengembalian (cepat).

Linux (setidaknya) memiliki opsi MAP_POPULATE (lihat 'man mmap') yang sesuai dengan pertanyaan Anda.


Linux
  1. Apa perbedaan antara menulis ke file dan memori yang dipetakan?

  2. Cat rekursif semua file menjadi satu file

  3. Linux:'Username' tidak ada dalam file sudoers. Kejadian ini akan dilaporkan

  1. Pengguna tidak ada dalam file sudoers. Kejadian ini akan dilaporkan

  2. Bagaimana cara mengarahkan output dari suatu perintah ke file ketika perintah tersebut akan meminta input pengguna?

  3. Apakah seluruh kernel dimuat ke dalam memori saat boot?

  1. Bagaimana cara Menyimpan output SHOW PROCESSLIST ke dalam file di MySQL?

  2. Salin Isi File Ke Clipboard Tanpa Menampilkan Isinya?

  3. Jika Saya Mengubah Izin Pada File Tar, Apakah Itu Berlaku Untuk File Di Dalamnya?