簡體   English   中英

我們如何為變量指定物理地址?

[英]How can we specify physical address for variable?

歡迎任何建議/討論!

問題實際上是簡短的標題,但我會解釋為什么我需要實際地址。


背景

這些天我對緩存和多核架構着迷,現在我很好奇緩存如何影響我們的程序,在並行環境下。

在某些CPU型號(例如,我的英特爾酷睿雙核T5800)中,L2緩存在核心之間共享。 因此,如果程序A正在訪問物理地址等的內存

0x00000000, 0x20000000, 0x40000000...

和程序B訪問數據

0x10000000, 0x30000000, 0x50000000...

由於這些地址共享相同的后綴,因此L2緩存中的相關集將經常刷新。 我們期望看到兩個程序相互爭斗,從內存緩慢讀取數據而不是緩存,盡管它們在不同的核心中分開。

然后我想在實踐中驗證結果。 在這個實驗中,我必須知道物理地址而不是虛擬地址。 但我怎么能應付這個呢?


第一次嘗試:

從堆,面具吃一大塊空間,並獲得一定的地址。

我的CPU有一個L2緩存,大小= 2048KB,關聯性= 8,因此物理地址如0x12340000, 0x12380000, 0x123c0000將與L2緩存中的第一個設置相關。

int HEAP[200000000]={0};
int *v[2];
int main(int argc, char **argv) {

    v[0] = (int*)(((unsigned)(HEAP)+0x3fffc) & 0xfffc0000);
    v[1] = (int*) ((unsigned)(v[0]) + 0x40000); 

    // one program pollute v[0], another polluting v[1]
}

遺憾的是,在虛擬內存的“幫助”下,變量HEAP在物理內存中並不總是連續的。 v[0]v[1]可能與不同的緩存集有關。


第二次嘗試

訪問/proc/self/mem ,並嘗試獲取內存信息。

嗯......似乎結果仍然是關於虛擬內存。

您對內存和這些地址的理解不完整/不正確。 從本質上講,你試圖測試的是徒勞的。

在用戶模式進程的上下文中,您看到的幾乎每個地址都是虛擬地址 也就是說,只有在該過程的上下文中才有意義的地址。 操作系統管理此虛擬內存空間(進程唯一)映射到內存頁面的映射。 任何給定時間的這些內存頁可以映射到被分頁的頁面(即駐留在物理RAM中) - 或者它們可以被分頁,並且僅存在於磁盤上的交換文件中。

因此,為了解決背景示例,這些地址來自兩個不同的過程 - 它絕對沒有什么可以嘗試和比較它們。 它們的代碼是否存在於任何緩存中取決於許多因素,包括處理器的緩存替換策略 ,OS啟用的緩存策略,其他進程的數量(包括內核模式線程),等等

在您的第一次嘗試中 ,您再也無法直接實際測試CPU緩存。 首先,你的大緩沖區不會在堆上。 它將成為可執行文件的數據部分(特別是.bss)的一部分。 該堆用於malloc()系列內存分配。 其次,如果你分配一些巨大的1GB區域並不重要,因為雖然它在你的進程的虛擬地址空間中是連續的,但是由操作系統來分配虛擬內存頁面,它認為合適的地方 - 這可能不是實際上是連續的。 同樣,您幾乎無法控制來自用戶空間的內存分配。 有沒有辦法從linux中的用戶空間分配連續的物理內存 ?” 最簡潔的答案是不。

/proc/$pid/maps也不會讓你到任何地方。 是的,那里列出了很多地址,但同樣,它們都在進程$pid的虛擬地址空間中。 有關這些的更多信息: 如何從Linux下的/ proc / $ pid / mem讀取?

暫無
暫無

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

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