Saya mendengar (membacanya di internet di suatu tempat) bahwa mmap() lebih cepat daripada IO berurutan. Apakah ini benar? Jika ya, mengapa lebih cepat?
Bisa jadi - ada pro dan kontra, tercantum di bawah ini. Saat Anda benar-benar memiliki alasan untuk peduli, selalu ukur keduanya .
Terlepas dari efisiensi IO yang sebenarnya, ada implikasi untuk cara kode aplikasi melacak saat perlu melakukan I/O, dan melakukan pemrosesan/pembuatan data, yang terkadang dapat memengaruhi kinerja secara dramatis.
- mmap() tidak membaca secara berurutan.2) mmap() harus mengambil dari disk itu sendiri sama seperti read() tidak3) Area yang dipetakan tidak berurutan - jadi tidak ada DMA (?).
Jadi mmap() seharusnya lebih lambat dari read() dari file? Manakah dari asumsi saya di atas yang salah?
-
salah...
mmap()
menetapkan wilayah ruang alamat virtual yang sesuai dengan konten file ... setiap kali halaman di ruang alamat itu diakses, RAM fisik ditemukan untuk mendukung alamat virtual dan konten disk yang sesuai dimasukkan ke dalam RAM itu. Jadi, urutan pembacaan dilakukan dari disk sesuai dengan urutan akses. Ini adalah mekanisme I/O yang "malas". Jika, misalnya, Anda perlu mengindeks ke tabel hash besar yang akan dibaca dari disk, makammap
ing file dan mulai melakukan akses berarti disk I/O tidak dilakukan secara berurutan dan oleh karena itu dapat mengakibatkan waktu yang lebih lama hingga seluruh file dibaca ke dalam memori, tetapi sementara itu terjadi pencarian berhasil dan pekerjaan yang bergantung dapat dilakukan, dan jika bagian dari file tidak pernah benar-benar diperlukan, mereka tidak dibaca (memungkinkan perincian disk dan halaman memori, dan bahkan ketika menggunakan pemetaan memori, banyak OS memungkinkan Anda untuk menentukan beberapa tip peningkatan kinerja / efisiensi memori tentang rencana Anda mengakses pola sehingga mereka dapat secara proaktif membaca ke depan atau melepaskan memori dengan lebih agresif karena mengetahui bahwa Anda tidak mungkin kembali ke sana). -
benar sekali
-
"Area yang dipetakan tidak berurutan" tidak jelas. Wilayah yang dipetakan memori "bersebelahan" (berurutan) dalam ruang alamat virtual. Kami telah membahas I/O disk yang berurutan di atas. Atau, apakah Anda memikirkan hal lain? Lagi pula, saat halaman mengalami kesalahan, halaman tersebut mungkin memang ditransfer menggunakan DMA.
Selain itu, ada alasan lain mengapa pemetaan memori dapat mengungguli I/O biasa:
- lebih sedikit penyalinan:
- seringkali rutin tingkat OS &pustaka melewatkan data melalui satu atau beberapa buffer sebelum mencapai buffer yang ditentukan aplikasi, aplikasi kemudian secara dinamis mengalokasikan penyimpanan, kemudian menyalin dari buffer I/O ke penyimpanan tersebut sehingga data dapat digunakan setelah file membaca selesai
- pemetaan memori memungkinkan (tetapi tidak memaksa) penggunaan di tempat (Anda bisa merekam pointer dan mungkin panjangnya)
- terus mengakses data di tempat berisiko meningkatkan kehilangan cache dan/atau bertukar nanti:file/memori-peta bisa lebih bertele-tele daripada struktur data yang dapat diurai, sehingga pola akses pada data di dalamnya bisa mengalami lebih banyak penundaan kesalahan di lebih banyak halaman memori
- pemetaan memori dapat menyederhanakan pekerjaan penguraian aplikasi dengan membiarkan aplikasi memperlakukan seluruh konten file sebagai dapat diakses, daripada mengkhawatirkan kapan harus membaca buffer lain penuh
- aplikasi lebih tunduk pada kebijaksanaan OS tentang jumlah halaman yang ada dalam RAM fisik pada satu titik waktu, secara efektif berbagi cache disk akses langsung dengan aplikasi
- serta komentar pemberi selamat di bawah, "menggunakan pemetaan memori biasanya Anda menggunakan lebih sedikit panggilan sistem"
- jika beberapa proses mengakses file yang sama, mereka seharusnya dapat berbagi halaman dukungan fisik
Itu juga alasan mengapa mmap
mungkin lebih lambat - baca posting Linus Torvald di sini yang menyebutkan mmap
:
...permainan tabel halaman bersama dengan overhead kesalahan (dan bahkan hanya TLB) lebih mudah daripada biaya menyalin halaman dengan cara streaming yang bagus...
Dan dari postingannya yang lain:
- biaya penyiapan dan pembongkaran yang cukup mencolok. Maksud saya terlihat . Hal-hal seperti mengikuti tabel halaman untuk menghapus peta semuanya dengan bersih. Ini pembukuan untuk memelihara daftar semua pemetaan. Ini adalah The TLB flush yang dibutuhkan setelah membongkar barang-barang.
- kesalahan halaman itu mahal. Begitulah cara pemetaan diisi, dan cukup lambat.
Linux memang memiliki "hugepages" (jadi satu entri TLB per 2MB, bukan per 4kb) dan bahkan Halaman Besar Transparan, di mana OS mencoba menggunakannya meskipun kode aplikasi tidak ditulis untuk menggunakannya secara eksplisit.
FWIW, terakhir kali ini muncul untuk saya di tempat kerja, input yang dipetakan memori 80% lebih cepat daripada fread
et al untuk membaca catatan basis data biner ke dalam basis data berpemilik, di Linux 64 bit dengan ~170 GB file.
mmap()
dapat berbagi antar proses.- DMA akan digunakan jika memungkinkan. DMA tidak memerlukan memori yang berdekatan -- banyak kartu high-end mendukung DMA scatter-gather.
- Area memori dapat digunakan bersama dengan cache blok kernel jika memungkinkan. Jadi ada penyalinan lessor.
- Memori untuk
mmap
dialokasikan oleh kernel, selalu selaras.