2010-11-01 162 views
3

這是cachegrind輸出的一部分。這部分代碼已執行1224次。 elmg1是一個無符號長數組,大小爲16 x 20。我的機器L1高速緩存大小爲32KB,64B高速緩存行大小和8路組相關聯。Cachegrind輸出解釋

  1. 爲(I = 0;我< 20; i ++在)78336 2448 2 50184 0 0 1224 0 0
  2. {
  3. telm01 = elmg1 [I]; 146,880 0 0 73,440 0 0 24,480 0 0
  4. telm31 =(telm01 < < 3)^ val1; 97,920 0 0 48,960 0 0 24,480 0 0
  5. telm21 =(telm01 < < 2)^(val1 >> 1); 146,880 1,224 1 48,960 0 0 24,480 0 0
  6. telm11 =(telm01 < < 1)^(val1 >> 2); 146880 0 0 48960 0 0 24,480 0 0
  7. }

答:我已經把它放在這裏的原因,就是在裏面的3號線的循環,我看到一些I1的惦記(一個L2錯過)。這有點混亂,我猜不出爲什麼?

B.我想優化(時間)一部分代碼。以上只是一小段片斷。我認爲在我的程序內存中存取成本很高。像上面的例子一樣,elmg1是一個16 x 20大小的無符號長整型數組。當我嘗試在代碼中使用它時,總會有一些錯誤,並且在我的程序中這些變量發生了很多。有什麼建議麼?

C.我需要分配和(有時初始化)這些無符號長整數。你能建議哪一個我更喜歡,calloc或數組聲明,然後顯式初始化。順便說一下,緩存處理它們的方式會有什麼不同嗎?

謝謝。

回答

3

您是否試圖展開循環?

  1. 我現在不擔心L1錯失。另外,1224次中的一個L2錯過了,CPU必須在某個時刻將值加載到緩存中。
  2. 與程序的其餘部分相比,此代碼的L2缺失的百分比是多少?
  3. 使用calloc(),如果數組大小始終相同,並且您使用大小的常量,則編譯器可以優化數組的歸零。此外,唯一會影響緩存行用法的是對齊,而不是如何初始化。

編輯:難以閱讀的數字,並閱讀錯誤的第一次。

可以確保我讀的數字正確的線路5:

Ir 146,880 
I1mr 1,224 
ILmr 1 
Dr 48,960 
D1mr 0 
DLmr 0 
Dw 24,480 
D1mw 0 
DLmw 0 

L1緩存被分成兩個32K字節緩存一個代碼I1和數據D1之一。 DL是由數據和指令共享的L2或L3緩存。

大量的I1mr是指令未命中而未丟失數據,這意味着循環代碼正在從I1指令緩存中彈出。

I1錯過第1行& 5總計3672是1224的3倍,所以每次循環運行時,都會得到3個I1高速緩存未命中,64Byte高速緩存行,這意味着您的循環代碼大小在128-192字節之間以覆蓋3個緩存行。所以那些I1在第5行錯過是因爲這是循環代碼跨越最後一個緩存行的地方。

I would recommend using KCachegrind for viewing the results from cachegrind

編輯:更多關於高速緩存行。

該循環代碼看起來並不像它自己調用1224次那樣,這意味着有更多的代碼將這些代碼從I1緩存中移出。

您的32K字節I1高​​速緩存分爲512個高速緩存行(每個64bytes)。 「8路組關聯」部分意味着每個存儲器地址僅被映射到這512個高速緩存行中的8個。如果你正在配置的整個程序是一個連續32K字節的內存塊,那麼它將全部放入I1緩存中,並且不會被彈出。這很可能不是這種情況,並且對於相同的8個高速緩存行將會有多於8個64字節的代碼塊內容。假設你的整個程序有1M字節的代碼(這包括庫),那麼每組8條高速緩存行將有大約32條(1Mbyte/32K字節)的代碼滿足這些相同的8條高速緩存行。

Read this lwn.net article for all the gory details about CPU caches

編譯器有時不能檢測出該程序的功能將是熱點(稱爲很多很多次),並且將codespots(即錯誤處理程序代碼,這幾乎從不運行)。 GCC具有功能屬性hot/cold,這將允許您將功能標記爲熱/冷,這將允許編譯器將熱功能組合在一塊內存中以獲得更好的緩存使用(即,冷碼不會將熱碼推出高速緩存)。

反正那些I1錯過真的不值得花時間去擔心。

+0

答:沒關係,但是爲什麼在第5行存在緩存未命中,而第3,4行的存儲空間不足。我是否需要自己指定對齊方式,我讀取默認情況下的malloc提供了8/16字節的對齊方式。 – anup 2010-11-01 08:57:09

+0

是的,malloc應該提供至少8byte的對齊方式,但這與64bytes緩存對齊不一樣。只有當你有一個64bytes的對象數組時,高速緩存對齊纔是重要的。如果數組未分配緩存對齊,則訪問數組中的任何一項可能會導致兩次緩存未命中,而不是一次。但在這種情況下,緩存對齊不是問題。 – Neopallium 2010-11-01 10:34:16

+0

感謝您的回覆。但是,有一件事我不明白這些與3個緩存行有什麼關係?應該有更多數量的緩存行。 – anup 2010-11-01 10:52:04