contributed by <Weinux
>
sysprog2017
w1
phonebook
Weinux
Sean1127
實驗的結果在用 gnuplot 的時候,除了append()
, findName()
之外還可以增加total
(也就是前面兩者相加)這一欄,實驗結果會更清楚
$ sudo dmidecode -t cache | more
跟$ lscpu
有什麼不同,結果有出入要如何解釋?
$ lscpu | grep cache
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 3072K
$ sudo dmidecode -t cache
# dmidecode 3.0
Getting SMBIOS data from sysfs.
SMBIOS 2.7 present.
Handle 0x000A, DMI type 7, 19 bytes
Cache Information
Socket Designation: CPU Internal L1
Configuration: Enabled, Not Socketed, Level 1
Operational Mode: Write Back
Location: Internal
Installed Size: 128 kB
Maximum Size: 128 kB
Supported SRAM Types:
Unknown
Installed SRAM Type: Unknown
Speed: Unknown
Error Correction Type: Single-bit ECC
System Type: Other
Associativity: 8-way Set-associative
這是在我的電腦上跑的結果,這邊寫我的L1 cache
有 128 kB,但上面寫我只有 64 kB
另外cache block
大小這個指令並沒有顯示,那要如何知道?
cache miss 的計算需要再確認
需要
回答以下問題:本例選用的 dataset (也就是輸入電話簿的姓名) 是否存在問題?
- 有代表性嗎?跟真實英文姓氏差異大嗎?
- 資料難道「數大就是美」嗎?
- 如果我們要建立符合真實電話簿情境的輸入,該怎麼作?
git commit message 寫的不錯!
不是第一次接觸這個作業, 所以這次主要目標
- 思考並實驗不同資料結構對於效能的影響(cache miss, append() & findName()時間比較).
- 以及思考電話簿字典檔的結構與可能問題
- 嘗試實作挑戰題
- 針對之前不熟悉的開發工具再學習與練習
Weinux
也可以使用指令得到電腦的系統架構圖
$ sudo apt-get install hwloc
$ lstopo
typedef struct __PHONE_BOOK_ENTRY {
char lastName[MAX_LAST_NAME_SIZE];
char firstName[16];
char email[16];
char phone[10];
char cell[10];
char addr1[16];
char addr2[16];
char city[16];
char state[2];
char zip[5];
struct __PHONE_BOOK_ENTRY *pNext;
} entry;
size of entry : 136 bytes
execution time of append() : 0.047197 sec
execution time of findName() : 0.005958 sec
Performance counter stats for './phonebook_orig' (100 runs):
1,955,691 cache-misses # 92.003% of all cache refs
2,125,670 cache-references
261,892,576 instructions # 1.38 insns per cycle
189,481,205 cycles
0.084996230 seconds time elapsed
size of entry : 32 bytes
execution time of append() : 0.042181 sec
execution time of findName() : 0.003178 sec
Performance counter stats for './phonebook_opt' (100 runs):
327,951 cache-misses # 59.565% of all cache refs
550,578 cache-references
250,927,988 instructions # 1.78 insns per cycle
141,234,044 cycles
0.070440497 seconds time elapse
Performance counter stats for './phonebook_hash' (100 runs):
885,265 cache-misses # 79.024 % of all cache refs ( +- 0.03% )
1,120,246 cache-references ( +- 0.13% )
350,152,192 instructions # 1.46 insns per cycle ( +- 0.21% )
239,262,574 cycles ( +- 0.34% )
0.107383867 seconds time elapsed
從 1980 年代開始,main memory 和 CPU 的速度差距急速拉大,主記憶體存取速度雖然時有提升,卻仍不及 CPU 的進展,因此需要一個中間層 cache 來彌補因為兩者間速度落差帶來的效能衝擊。
原理:cache 利用記憶體架構的兩大原則來設計
1. Temporal Locality: 剛剛用過的記憶體很容易再被使用(例如,for迴圈)
2. Spatial Locality: 如果一個記憶體剛剛使用過,他附近的記憶體位址也很可能被使用到(例如,陣列存取)
"cache" 是為了讓資料存取的速度適應 CPU 的處理速度允許 CPU 直接到 cache memory 查看所需資料是否存在。若是,則直接存取不必再到 main memory —— 減少到 main memory 存取的次數,解決 main memory 存取不夠快的問題。
set associative:set associative 的方式,也就是把 cache 分成多個 set,CPU必須檢查指定set內的每個block是否有可用的cache。最極端的情況下就是Fully Associative,也就是CPU要檢查cache內所有的block。
更多內容如下:
Cache Miss的計算:以 phonebook 為例
先透過指令查詢硬體規格如下:
$ sudo dmidecode -t cache | more
需要有多少block?
(考慮main.c findName() & append 這2個function 因為 linked-list 跟搜尋存取花最多時間)
350000 筆資料 * 每筆 144 byte = 50400000 byte
50400000 byte / 64byte ( block size ) * 2次 function = 1575000 block
讀一個block是一次 reference
執行 phonebook 程式確認 perf 中 cache 相關訊息
$ make cache-test
size of entry : 136 bytes
execution time of append() : 0.047197 sec
execution time of findName() : 0.005958 sec
Performance counter stats for './phonebook_orig' (100 runs):
1,955,691 cache-misses # 92.003% of all cache refs
2,125,670 cache-references
261,892,576 instructions # 1.38 insns per cycle
189,481,205 cycles
cache 有幾個 set?
cache 32K Byte / block 64 Byte = 512 block
512 / 8-way set = 64 個
一個 cache line 可以存多少筆 entry
cache miss
1,575,000 ( 總 block ) / 3(一個 entry 需要3 block) = 525,000 組 entry
525,000 / 64( index 數) = 8,203 ( tag 數,填到相同 index 的個數 )
由上知一個 cache line 最多可以放 2 組 entry,所以有兩次機會
8,203 / 2 = 4,101 ( 可能被對到次數 )
4,101 * 64 ( index 數) * 3 ( entry 佔的 block 數) = 787392 ( cache hit 次數 )
1,575,000 - 787,392 = 787,608 ( cache-miss)
787,608 / 1,575,000 = 50%(miss rate) ???
驗證助教的共筆,發現根據同樣方式計算. cache-miss rate 結果也是50%左右, 而非程式中的 92%, 需要再確認 cache 計算方式
$ ./ "執行檔案名稱" & sudo perf top -p $!