contributed by <andy19950
>
jserv
append()
中,malloc()
是個顯著的時間開銷,缺乏減緩效能衝擊的方案,而且沒考慮到 malloc()
失敗的情況phonebook_orig
執行都會失敗:$ ./phonebook_orig
size of entry : 136 bytes
程式記憶體區段錯誤
main.c
無法透過 function pointer 來切換和比較不同實做的效能落差,應該先設計一份可通用的軟體界面,然後將 binary tree, hash table, trie 等不同實做機制加入append()
和 findName()
時間加入統計的意義不大,真實應用往往是個別操作,特別在圖表的呈現
typedef struct __BOOK_INDEX_ENTRY {
char lastName[MAX_LAST_NAME_SIZE];
struct __BOOK_INDEX_ENTRY *pNext;
struct __PHONE_BOOK_ENTRY *detail;
} entry;
typedef struct __PHONE_BOOK_ENTRY {
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];
};
Performance counter stats for './phonebook_orig' (100 runs):
2,130,447 cache-misses #94.137 % of all cache refs ( +- 0.12% )
2,263,135 cache-references ( +- 0.12% )
261,167,670 instructions #1.29 insns per cycle ( +- 0.02% )
202,575,413 cycles ( +- 0.90% )
0.073190313 seconds time elapsed ( +- 1.60% )
Performance counter stats for './phonebook_opt' (100 runs):
423,413 cache-misses #63.932 % of all cache refs ( +- 1.04% )
662,282 cache-references ( +- 1.36% )
243,923,231 instructions #1.66 insns per cycle ( +- 0.02% )
146,548,771 cycles ( +- 1.06% )
0.048755741 seconds time elapsed ( +- 2.23% )
unsigned int hash(char *name)
{
unsigned int num=0;
for(int i=1; i<strlen(name); i++) {
num += name[i] ;
}
num %= (TABLE_SIZE / 26);
num += (name[0] - 'a') * (TABLE_SIZE / 26);
return num % TABLE_SIZE;
}
/* Version 1 append immediately */
int loc = hash(lastName);
e->pNext = hash_table[loc];
hash_table[loc] = e;
Performance counter stats for './phonebook_opt_v2' (100 runs):
214,742 cache-misses #72.231 % of all cache refs ( +- 0.36% )
297,299 cache-references ( +- 0.59% )
296,020,025 instructions #1.98 insns per cycle ( +- 0.34% )
149,720,323 cycles ( +- 0.39% )
0.055791399 seconds time elapsed ( +- 2.73% )
/* Version 2 append to "the end of" linked list */
if(hash_table[loc] == NULL)
hash_table[loc] = e;
else{
entry* ptr = hash_table[loc];
while(ptr->pNext != NULL)
ptr = ptr->pNext;
ptr->pNext = e;
}
Performance counter stats for './phonebook_opt_v2' (100 runs):
273,206 cache-misses #6.246 % of all cache refs ( +- 1.18% )
4,373,970 cache-references ( +- 0.53% )
362,481,024 instructions #0.79 insns per cycle ( +- 0.18% )
458,004,336 cycles ( +- 0.34% )
0.166064657 seconds time elapsed ( +- 0.97% )
fprintf(output, "append() %.4f %.4f %.4f\n",orig_sum_a / 100.0, opt_sum_a / 100.0, opt_sum2_a / 100.0);
fprintf(output, "findName() %.4f %.4f %.4f", orig_sum_f / 100.0, opt_sum_f / 100.0, opt_sum2_f / 100.0);
/*------[:.num] 修改num能調整 y軸長度------*/
plot [:][:.1]'output.txt' using 2:xtic(1) with histogram title 'original', \
/*-----第一個括號為結果的x軸位置,第二個為y軸位置-----*/
'' using ($0-0.1):(0.01):2 with labels title ' ', \
'' using ($0+0.1):(0.015):3 with labels title ' ', \
'' using ($0+0.4):(0.01):4 with labels title ' '
/*-----新增hash function的欄位-----*/
'' using 4:xtic(1) with histogram title 'hash function' , \
'' using ($0+0.4):(0.01):4 with labels title ' '
使用第一種append版本
使用第二種append版本