contributed by < s8w1e2ep
>
sys2017
s8w1e2ep
phonebook
davis8211
各種字符串Hash函數比較
這個網頁裡面有各個hash function的比較實驗,其中BKDR hash的分數最高,因此我選擇使用BKDR hash function。s8w1e2ep
44,887是一個質數,會選擇這麼大的數字,是因為 data set 有35萬筆資料。如果 size 太小,發生 collision 的機率會提高。導致搜尋時間變長。而 size 大到某個程度後,發生 collision 的機率相差不大,搜尋效率也不會變得更好,反而會佔取額外的空間。s8w1e2ep
entry *append(char lastName[], entry *e)
{
unsigned int hashValue = BKDRHash(lastName);
e = (entry *) malloc(sizeof(entry));
e->pNext = hashTable[hashValue];
strcpy(e->lastName, lastName);
e->detailEntry = NULL;
e->pNext = NULL;
hashTable[hashValue] = e;
return e;
}
確實會蓋過過去儲存的資料,我會再做修改。s8w1e2ep
OS: Ubuntu 16.04.1 (LTS)
Architecture: x86_64
CPU 作業模式: 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
每核心執行緒數:1
每通訊端核心數:4
Socket(s): 1
NUMA 節點: 1
供應商識別號: GenuineIntel
CPU 家族: 6
型號: 158
Model name: Intel(R) Core(TM) i5-7500 CPU @ 3.40GHz
製程: 9
CPU MHz: 799.987
CPU max MHz: 3800.0000
CPU min MHz: 800.0000
BogoMIPS: 6800.00
虛擬: VT-x
L1d 快取: 32K
L1i 快取: 32K
L2 快取: 256K
L3 快取: 6144K
NUMA node0 CPU(s): 0-3
PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\[\033[01;33m\]$\[\033[00m\] '
set ai
syntax on
set background=dark
set enc=utf8
set hls
set number
map <F4> : set nu!<BAR>set nonu?<CR>
set ic
set expandtab
set tabstop=4
set shiftwidth=2
$ sudo sh -c " echo 0 > /proc/sys/kernel/kptr_restrict"
接著輸入$ perf top
結果出現
一開始想法是用Vim直接改/proc/sys/kernel/perf_event_paranoid這個檔案,
後來發現無法強制改值。最後參考了這位大大的共筆。
輸入下列指令
$ sudo sh -c " echo 1 > /proc/sys/kernel/perf_event_paranoid"
再執行$ perf top
,就解決啦!
輸入下列指令就可以依照 K&R style 自動排版程式碼
$ astyle --style=kr --indent=spaces=4 --indent-switches --suffix=none *.[ch]
資料在 memory 與 cache 傳送時,會以固定大小的block型式傳遞,我們稱為 cache line 或是 cache block。當1個 cache line 從 memory 複製到 cache 時,1個 cache entry 會被創造。 Cache entry 包含了複製的資料以及請求的記憶體位址(又稱為 tag )。
當程序需要讀取或寫入資料到記憶體位址時,首先會確認 cache 中對應的 entry 。並確認任一個可能包含此位址的 cahce line 的內容。如果程序在 cache 中找到位址,就會發生 cache hit ;反之,則會發生 cache miss 。 在 cache hit 的情況下,程序可以從 cache line 中立即的讀取或寫入資料;在 cache miss 的情況下, cache 會分配一個新的 entry 的空間並將資料從記憶體複製到 entry 中,然後用 cache 的內容去完成請求。
發生 Cache miss 的情況分為三種
Cache entry structure
tag | index | block offset |
---|
the length of address
- index
- block offset
bits輸入下列指令,可以得到自己電腦的cache line size,我的電腦是64B。
$ cat /sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size
執行下列指令可以查看 cache 詳細資訊
$ sudo dmidecode -t cache | more
我的電腦是64位元的 OS ,因此位址長度為 64 bits。而 cache block 大小為 64B,L1 cache 使用的是 8 - way associative, 且 L1d cache 大小為 32KB。
$ echo 1 | sudo tee /proc/sys/vm/drop_caches
$ ./phonebook_orig
size of entry : 136 bytes
execution time of append() : 0.035636 sec
execution time of findName() : 0.005177 sec
$ make cache-test
Performance counter stats for './phonebook_orig' (100 runs):
4,586,848 cache-misses # 91.197 % of all cache refs ( +- 0.15% )
5,029,615 cache-references ( +- 0.09% )
262,487,884 instructions # 1.45 insn per cycle ( +- 0.02% )
180,634,865 cycles ( +- 0.08% )
0.050913126 seconds time elapsed ( +- 0.18% )
typedef struct __PHONE_BOOK_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];
detail *detailEntry;
struct __PHONE_BOOK_ENTRY *pNext;
} entry;
size of entry : 32 bytes
execution time of append() : 0.042310 sec
execution time of findName() : 0.001569 sec
$ make cache-test
Performance counter stats for './phonebook_opt' (100 runs):
1,401,857 cache-misses # 62.629 % of all cache refs ( +- 0.45% )
2,238,341 cache-references ( +- 0.12% )
244,525,333 instructions # 2.09 insn per cycle ( +- 0.02% )
117,255,055 cycles ( +- 0.10% )
0.032406767 seconds time elapsed ( +- 0.28% )
unsigned int BKDRHash(char *str)
{
unsigned int seed = 131, hash = 0;
while(*str) {
hash = hash * seed + (*str++);
}
return hash % MAX_HASH_TABLE_SIZE;
}
size of entry : 32 bytes
execution time of append() : 0.034605 sec
execution time of findName() : 0.000000 sec
$ make cache-test
Performance counter stats for './phonebook_hash' (100 runs):
586,421 cache-misses # 37.400 % of all cache refs ( +- 0.51% )
1,567,973 cache-references ( +- 0.17% )
242,581,266 instructions # 1.93 insn per cycle ( +- 0.02% )
125,639,830 cycles ( +- 0.10% )
0.035417917 seconds time elapsed ( +- 0.23% )