contributed by <aweimeow
>
sysprog21
aweimeow
HuangWenChen
這邊看到 @louielu 用了 lstopo
這個工具覺得很酷所以也想安裝一下,這邊紀錄一下安裝的流程:
wget https://www.open-mpi.org/software/hwloc/v1.11/downloads/hwloc-1.11.4.tar.gz
tar zxvf hwloc-1.11.4.tar.gz
cd hwloc-1.11.4
cat README # 不過他的 README 沒有說明要怎麼安裝 Orz
./configure
make
sudo make install
BUT … !
libhwloc.so.5: cannot open shared object file: No such file or directory
後來找了一下發現 libhwloc.so.5
在 /usr/local/lib
裡面,所以我手動修改了 /usr/local/lib
,再執行 ldconfig
輸出:
Machine (7879MB)
Package L#0 + L3 L#0 (3072KB)
L2 L#0 (256KB) + L1d L#0 (32KB) + L1i L#0 (32KB) + Core L#0
PU L#0 (P#0)
PU L#1 (P#1)
L2 L#1 (256KB) + L1d L#1 (32KB) + L1i L#1 (32KB) + Core L#1
PU L#2 (P#2)
PU L#3 (P#3)
HostBridge L#0
PCIBridge
PCI 10de:1341
PCI 8086:0416
GPU L#0 "card0"
GPU L#1 "renderD128"
GPU L#2 "controlD64"
PCIBridge
PCI 10ec:8168
Net L#3 "eth0"
PCIBridge
PCI 168c:0036
Net L#4 "wlan0"
PCI 8086:8c03
Block(Removable Media Device) L#5 "sr0"
Block(Disk) L#6 "sda"
根據 wiki 上面的說明,我的操作如下,過程沒有碰到任何問題:
$ sudo apt-get install linux-tools-common
$ sudo apt-get install linux-tools-4.2.0-27-generic linux-cloud-tools-4.2.0-27-generic
perf stat 存取局域性結果差異:
$ perf stat --repeat 5 -e cache-misses,cache-references,instructions,cycles ./test
Performance counter stats for './test' (5 runs):
2,614,830 cache-misses # 2.525 % of all cache refs
100,415,393 cache-references
2,006,482,671 instructions # 0.81 insns per cycle
2,409,393,663 cycles
0.803709786 seconds time elapsed ( +- 14.38% )
$ perf stat --repeat 5 -e cache-misses,cache-references,instructions,cycles ./test
Performance counter stats for './test' (5 runs):
217,059 cache-misses # 63.407 % of all cache refs
347,854 cache-references
2,005,971,913 instructions # 1.93 insns per cycle
1,032,907,799 cycles
0.334975609 seconds time elapsed ( +- 0.97% )
$ apt-get install gnuplot
$ apt-get install astyle
在我的電腦上,未修改的程式碼的 cache-miss 為 81.418%
Performance counter stats for './phonebook_orig' (100 runs):
1,154,821 cache-misses # 81.418 % of all cache refs
1,389,198 cache-references
263,656,721 instructions # 1.06 insns per cycle
240,380,961 cycles
0.081547701 seconds time elapsed ( +- 0.82% )
以下先試試使用改變資料結構來改善效能
我們先從 phonebook_opt.h
來開始下手,讓我們先思考一個問題:在要查找電話簿時, key 應該是什麼?想當然是名字,在翻找電話簿時,找到名字後,跟隨在其後的地址、信箱、電話號碼 … 才會需要被看到。
因此,來修改一下程式碼,將 firstName
, email
, phone
, … 這些資料先藏起來放到另一個資料結構中,我把它取名為 detail
,搜尋到時可以存取這一筆 entry 裡面的細節(信箱、電話、…)
typedef struct __PHONE_BOOK_ENTRY_DETAIL {
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];
} detail;
typedef struct __PHONE_BOOK_ENTRY {
char lastName[MAX_LAST_NAME_SIZE];
struct detail *detail;
struct __PHONE_BOOK_ENTRY *pNext;
} entry;
這樣子改善之後,我們的 cache-miss
會下降多少呢?
Performance counter stats for './phonebook_opt' (100 runs):
158,618 cache-misses # 38.030 % of all cache refs
437,759 cache-references
245,272,988 instructions # 1.52 insns per cycle
163,283,836 cycles
0.053033708 seconds time elapsed ( +- 1.06% )
從輸出當中我們可以觀察到 cache-miss
從 81.418% 下降到 38.030%
下圖是這個階段執行完的 function 時間比較:
可以從圖中發現,時間也有明顯的下降。
Hash Function 選用 djb2
不過真的很久沒有碰過 C 語言了,改改 header file 還可以,要重拾三年前的 C 語言讓我碰到滿滿的挫折(或者說以前根本沒好好學 C)
無法用 C 語言開發出 C compiler & UNIX 等級的軟體,就是不懂 C 語言,沒有「略懂」這回事。 jserv
entry *people;
strcpy(people->lastName, lastName);
然後就 Segment Fault
了,後來查到問題才發現原來我這樣子作是不對的。
在這邊都是指標,指標儲存的是一個記憶體位址,所以我直接把 lastName
copy 到 people->lastName
就相當於:以 lastName
為 'AAAA' 來說,就是把 0x41414141 寫到 people->lastName
,所以這個 pointer 就會指到這個奇怪的地址去,所以就錯了。