簡體   English   中英

Linux Kernel - msync 鎖定行為

[英]Linux Kernel - msync Locking Behavior

我正在研究一個將固定大小的塊(例如 4k)中的隨機數據寫入大緩沖區文件中的隨機位置的應用程序。 我有幾個進程(不是線程)這樣做,每個進程都有自己的緩沖區文件分配。

如果我使用 mmap+msync 將數據寫入和持久化到磁盤,我會看到 16 個進程的性能峰值,以及更多線程(32 個進程)的性能下降。

如果我使用 open+write+fsync,我看不到這樣的尖峰,而是一個性能平台(並且 mmap 比 open/write 慢)。

我已經多次閱讀 [1,2],mmap 和 msync 都可以鎖定。 通過 vtune,我分析到我們確實在自旋鎖定,並且在clear_page_ermsxas_load函數上花費的時間最多。

但是,在閱讀 msync [3] 的源代碼時,我無法理解這些鎖是全局的還是每個文件的。 論文 [2] 指出鎖位於 kernel 中的基數樹上,它們是每個文件的,但是,由於我確實觀察到 kernel 中的一些自旋鎖,我相信有些鎖可能是全局的,因為我每個文件都有一個文件過程。

您是否解釋了為什么我們在 16 個進程中對 mmap 和對 msync 的鎖定行為的輸入有如此高的峰值?

謝謝!

最佳,馬克西米利安

[1] https://kb.pmem.io/development/100000025-Why-msync-is-less-optimal-for-persistent-memory/

[2] 為快速存儲設備優化內存映射 I/O,Papagiannis 等人,ATC '20

[3] https://elixir.bootlin.com/linux/latest/source/mm/msync.c

在 4.19 kernel 源中,當前任務保留自己的 mm_struct,其中包含一個信號量,用於仲裁對所有正在同步的 memory 區域的訪問。 因此,作用於您的一個緩沖區文件的進程中的所有線程都將采用此信號量,對文件的某些區域進行操作,並釋放該信號量。

雖然我無法合理化您遇到性能懸崖的 16 個進程的確切數量,但很明顯,當您使用 mmap() 時,您會強制進入 VM_SHARED 的 msync(M_SYNC) 代碼部分。 這會調用 vfs_fsync_range() 並保證會發生實際的同步磁盤 I/O,這通常會減慢顯示速度:它不允許對 I/O 進行有利的分組以節省成本,並且傾向於最大化等待磁盤 I 所花費的實際時間/O 完成。

為避免這種情況,請確保進程中的每個線程都管理緩沖區文件中 4K 塊的專用子集,避免緩沖區文件上的 mmap(),並安排異步 I/O。 只要您在緩沖區文件本身上避免 mmap() ,每個線程將單獨(安全地,如果您設計得好)寫入緩沖區文件自己的部分。 因此,您將能夠將所有 I/O 指定為異步的,這應該允許更好的聚合並顯着提高應用程序的性能,即避免出現 16 個進程或任何最終數字的懸崖。 顯然,如果另一個寫入同一塊的請求,您仍然必須確保寫入其中一個塊的任何線程要么完成該寫入,要么尚未開始它(並丟棄任何這樣做的請求)隨之而來。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM