contributed by <shelly4132
>
0140454
閱讀 重新理解數值 裡頭關於 count leading zero (clz) 的描述,設計實驗,比較 32-bit 數值對以下實做的效能差異:
int __builtin_clz (unsigned int x)
利用GCC提供的__builtin_clz (unsigned int x)
去檢查重新理解數值裡,iteration、binary search、byte shift 算出來的結果。
for(uint32_t i=1; i<UINT_MAX; i++){
#if defined(ITERATIVE)
assert(iterative_clz(i) == __builtin_clz(i));
#endif
#if defined(BINARY)
assert(binary_clz(i) == __builtin_clz(i));
#endif
#if defined(BYTE)
assert(byte_clz(i) == __builtin_clz(i));
#endif
}
printf("Done!\n");
參照老師給的範例去改的,其實算法都大同小異。
int recursive_clz(uint32_t x, int shift)
{
if(x == 0)
return 32;
if(!shift)
return 0;
uint16_t upper = (x >> shift);
uint16_t lower = (x & (0xFFFF >> (16 - shift)));
return upper ? recursive_clz(upper,shift>>1) : shift + recursive_clz(lower,shift>>1);
}
用之前教的time指令去看每一種算法的時間,可以發現recursive的版本比其他版本的時間要高出許,這可能是因為recursive的版本多了很多function call的成本。
time ./check_iterative
Done!
86.34user 0.05system 1:26.39elapsed 100%CPU (0avgtext+0avgdata 1304maxresident)k
0inputs+0outputs (0major+64minor)pagefaults 0swaps
time ./check_binary
Done!
28.20user 0.00system 0:28.20elapsed 100%CPU (0avgtext+0avgdata 1168maxresident)k
0inputs+0outputs (0major+61minor)pagefaults 0swaps
time ./check_byte
Done!
30.46user 0.02system 0:30.49elapsed 99%CPU (0avgtext+0avgdata 1168maxresident)k
0inputs+0outputs (0major+61minor)pagefaults 0swaps
time ./check_recursive
Done!
180.16user 0.27system 3:00.43elapsed 100%CPU (0avgtext+0avgdata 1256maxresident)k
0inputs+0outputs (0major+61minor)pagefaults 0swaps