簡體   English   中英

惰性過度分配和 calloc

[英]lazy overcommit allocation and calloc

知道的人可以解釋一下延遲堆存儲如何與 calloc/realloc 的內存歸零保證交互嗎? 具體來說,我想知道:

  1. 如果/當零寫入會導致存儲立即出現故障
  2. 如果/當不是,我是否應該關注可能發生故障的上下文(例如,從程序集中完成的讀取系統調用)

calloc可以從操作系統獲得保證為零的頁面,從而完全避免在用戶空間中寫入零。 (特別是對於大型分配,否則如果有任何大小合適的空閑列表條目,它將從空閑列表中歸零。)這就是惰性的來源。

因此,您的頁面將從mmap(MAP_ANONYMOUS) ,不受用戶空間的影響。 讀取它會觸發軟頁錯誤,即寫時復制將其映射到共享的零物理頁。 (很有趣的事實是,在大量 calloc 分配上以只讀方式循環時,您可能會遇到 TLB 未命中但 L1d / L2 緩存命中)。

寫入那個頁面/其中一個頁面(作為第一次訪問,或者在它被 CoW 映射到零頁面之后)將軟頁面錯誤,Linux 的頁面錯誤處理程序將分配一個新的物理頁面並將其歸零 (所以在缺頁后,整個頁面在 L1d 緩存中通常是熱的,或者至少是 L2,即使使用 faultaround 准備更多的頁面並將它們連接到頁表中以減少頁面故障的數量,如果有相鄰的頁面也是懶惰分配的)。


但是不,除了一般的性能調整之外,您通常不需要擔心它。 如果您在邏輯上擁有一些 memory,您可以要求read將數據放入其中。 libc 包裝器沒有在那里進行任何特殊的重試; 所有的魔法(檢查目標頁面是否存在並將其視為軟或硬頁面錯誤)都發生在內核的read實現中,作為copy_to_user的一部分。

(Basically a memcpy from kernel memory to user-space, with permission checking that can make it return -EFAULT if you pass the kernel a pointer that you don't even logically own. ie memory that would segfault if you touched it from user-空格。請注意,您不會從read(0, NULL, 1)獲得 SIGSEGV,只是一個錯誤。使用strace./a.out來查看,作為在手寫 asm 中實際實施錯誤檢查的替代方法。 )

暫無
暫無

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

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