2 回答

TA貢獻1804條經驗 獲得超2個贊
這本書正在談論“磁盤結構”。在此上下文中,頁面僅表示數據塊。磁盤訪問在扇區或集群中工作,因此應針對局部性優化數據,以便盡可能地適應這些塊。數據庫文件設計的挑戰是將數據的時間局部性轉換為空間局部性。
但這個概念也適用于RAM。在用戶空間虛擬內存中的頁面級別工作僅意味著了解底層內存體系結構并對其進行優化。
在 x86 上,用戶空間虛擬內存以 4 KB* 的頁為單位進行組織。
這意味著,在處理大量數據時,使用內存區域是值得的,內存區域是 4 KB 的倍數,與 4 KB 對齊。
在C中,有很多方法可以實現這一目標,例如.aligned_alloc
但是Go走得更遠 - 它已經至少在頁面大?。ㄔ贛ac,BSD,Linux和Windows上)對齊了大型數組。
func main() {
buf := make([]byte, 1024*1024)
fmt.Printf("%p\n", unsafe.Pointer(&buf[0]))
}
將打印如下內容:
0xc000180000
如果您遇到不這樣做的實現,您始終可以“手動”對齊切片,方法是分配PageSize-1額外的字節,然后跳過開頭的字節,這些字節不是從PageSize的倍數開始的,使用對齊公式:byte
偏移量 = (對齊 - 基數) & (對齊 - 1)
func main() {
buf := make([]byte, 1024*1024 + 4096 - 1)
base := unsafe.Pointer(&buf[0])
offset := (4096 - uintptr(base)) & (4096 - 1)
aligned := buf[offset:]
fmt.Printf("base : %p\n", unsafe.Pointer(&buf[0]))
fmt.Printf("aligned: %p\n", unsafe.Pointer(&aligned[0]))
}
(想不出上面會打印不同值的平臺)
* 某些平臺支持 2MB 和 1GB 頁面的大頁面。Go 會在可用時自動使用它們。

TA貢獻1821條經驗 獲得超5個贊
我可能錯過了一些東西,但是使用物理內存(與虛擬內存相反)不是語言功能,而是操作系統
的功能。
每個操作系統都提供了使用實際地址空間的方法,這些服務需要提升的權限,并作為驅動程序/內核模塊提供,并使用此訪問進行內存映射IO或預分配物理內存塊(在MMI將其用作分頁內存之前)。
我想在系統負載(通過驅動程序)上預先分配內存塊并使用它是您希望做的。
如果您打算在“物理內存”上訪問“虛擬內存”,我會勸阻您并說這是一個非常微妙和脆弱的機制,除非您發現這樣做的巨大優勢,否則我看不到任何理由走這條路。
- 2 回答
- 0 關注
- 106 瀏覽
添加回答
舉報