簡體   English   中英

如何通過IO時序測量找到L1緩存行大小的大小?

[英]How to find the size of the L1 cache line size with IO timing measurements?

作為一項學校作業,我需要找到一種方法來獲取L1數據緩存行大小,而無需讀取配置文件或使用api調用。 假設使用內存訪問讀/寫時序來分析和獲取此信息。 那我該怎么做呢?

在完成另一部分任務的不完整嘗試中,為了找到緩存的級別和大小,我有:

for (i = 0; i < steps; i++) {
    arr[(i * 4) & lengthMod]++;
}

我想也許我只需要改變第2行, (i * 4)部分? 所以一旦我超過緩存行大小,我可能需要更換它,這需要一些時間? 但它是如此直截了當? 所需的塊可能已經存在於內存中? 或者perpahs我仍然可以依靠這樣一個事實,即如果我有足夠大的steps ,它仍然會非常准確地運作?

UPDATE

下面是對GitHub的嘗試 ...主要部分如下

// repeatedly access/modify data, varying the STRIDE
for (int s = 4; s <= MAX_STRIDE/sizeof(int); s*=2) {
    start = wall_clock_time();
    for (unsigned int k = 0; k < REPS; k++) {
        data[(k * s) & lengthMod]++;
    }
    end = wall_clock_time();
    timeTaken = ((float)(end - start))/1000000000;
    printf("%d, %1.2f \n", s * sizeof(int), timeTaken);
}

問題是時間似乎沒有太大差異。 僅供參考。 因為它用於L1緩存。 我有SIZE = 32 K(數組的大小)

分配一個BIG char數組(確保它太大,不適合L1 L2緩存)。 用隨機數據填寫。

n個字節為步長開始遍歷數組。 對檢索到的字節執行某些操作,例如對它們進行求和。

基准測試並計算您可以使用不同的n值處理多少字節/秒,從1開始並計數到1000左右。 確保您的基准測試打印出計算的總和,因此編譯器無法優化基准測試代碼。

n ==您的緩存行大小時, 每次訪問都需要在L1緩存中讀取新行。 因此,基准測試結果應該在這一點上變得非常急劇。

如果數組足夠大,那么當你到達終點時,數組開頭的數據將再次超出緩存,這就是你想要的。 因此,在增加n並重新開始之后,結果將不會受到緩存中已有數據的影響。

看看Calibrator ,所有的工作都受版權保護,但源代碼是免費提供的。 從它的文檔想法來計算緩存行大小聽起來比這里已經說過的更有教育意義。

我們的校准器工具的基本思想是擁有一個微基准測試,其性能僅取決於發生的高速緩存未命中的頻率。 我們的校准器是一個簡單的C程序,主要是一個執行一百萬次內存讀取的小循環。 通過改變步幅(即,兩個后續存儲器訪問之間的偏移)和存儲區域的大小,我們強制改變緩存未命中率。

原則上,高速緩存未命中的發生由陣列大小決定。 一旦數據加載到緩存中,適合L1緩存的數組大小不會生成任何緩存未命中。 類似地,超過L1高速緩存大小但仍然適合L2的陣列將導致L1未命中但沒有L2未命中。 最后,大於L2的陣列導致L1和L2未命中。

高速緩存未命中的頻率取決於訪問跨度和高速緩存行大小。 當步幅等於或大於高速緩存行大小時,每次迭代都會發生高速緩存未命中。 如果步幅小於高速緩存行大小,則僅每n次迭代(平均)發生高速緩存未命中,其中n是高速緩存行大小/步幅的比率。

因此,我們可以通過將沒有未命中的執行時間與執行時間進行比較來計算高速緩存未命中的等待時間,每次迭代恰好一次丟失。 這種方法只有在內存訪問是純順序執行的情況下才有效,即我們必須確保兩個或多個加載指令,內存訪問和純CPU工作都不能重疊。 我們使用一個簡單的指針追蹤機制來實現這一點:我們訪問的內存區域被初始化,以便每個load在下一次迭代中返回后續加載的地址。 因此,超標量CPU無法通過推測執行來隱藏內存訪問延遲。

為了測量緩存特性,我們多次運行實驗,改變步幅和數組大小。 我們確保步幅至少在4個字節和最大預期高速緩存行大小的兩倍之間變化,並且數組大小從最小預期高速緩存大小的一半變化到最大預期高速緩存大小的至少十倍。

我不得不注釋#include "math.h"來編譯它,之后它發現我的筆記本電腦的緩存值正確。 我也無法查看生成的postscript文件。

您可以在匯編程序中使用CPUID函數,雖然不可移植,但它會為您提供所需的功能。

對於Intel微處理器,可以通過在調用cpuid函數0x1后將bh乘以8來計算高速緩存行大小。

對於AMD微處理器,數據高速緩存行大小在cl中,並且在調用cpuid函數0x80000005之后指令高速緩存行大小為dl。

我從這篇文章中得到了這個。

我認為你應該編寫程序,它將以隨機順序直接遍歷數組,因為現代流程會進行硬件預取。 例如,make int of int,其值將是下一個單元格的數量。 我做了類似的程序1年前http://pastebin.com/9mFScs9Z對不起我的英語,我不是母語。

了解如何實現memtest86。 他們以某種方式測量和分析數據傳輸速率。 速率變化點對應於L1,L2的大小和可能的L3高速緩存大小。

如果你陷入困境並無法離開,請看這里

有手冊和代碼可以解釋如何做你要問的事情。 代碼質量也很高。 看看“子程序庫”。

代碼和手冊基於X86處理器。

我認為應該對使用一定量內存的操作進行計時。 然后逐步增加操作使用的內存(例如操作數)。 當操作性能急劇下降時,您已找到限制。

我只需要讀取一堆字節而不打印它們(打印會使性能如此糟糕而成為瓶頸)。 在讀取時,時間應該與讀取的字節數直接成比例,直到數據不再適合L1,然后您將獲得性能損失。

您還應該在程序開始時和開始計算時間之前分配一次內存。

只是一張紙條。

高速緩存行大小在少數ARM Cortex系列中是可變的,並且可以在執行期間更改,而無需向當前程序發送任何通知。

暫無
暫無

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

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