or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Syncing
xxxxxxxxxx
2020q3 Homework3 (quiz3)
contributed by <
Sisker1111
>tags:
進階電腦系統理論與實作
1. ASR
考慮到程式碼的相容性,目的是實作一套可跨越平台的 ASR,假設在二補數系統,無論標的環境的 shift 究竟輸出為何,我們的 ASR 總可做到:
-3 是 (-5) / 2 的輸出,並往負無限大的方向前進
fix ^ (fix >> n)
會變成2b'000.....0 ^ 2b'000.....0 = 2b'000.....0
(不影響結果)fix ^ (fix >> n)
會變成2b'111.....1 ^ 2b'000.....1 = 2b'111.....0
( 1 的數量等同 n)2. int __builtin_ctz & int __builtin_clz
用 __builtin_ctz 來實作 LeetCode 342 . Power of Four,假設 int 為 32 位元寬度。實作程式碼如下:
此題是要確認該數字是否為 4 的冪次方,若該數為 4 的冪次方 32bits 中只會有 1 個 bit 為 1 且該 bit 右邊的 bits 數量應該偶數個,
num > 0 && num & (num-1)
首先確認該數是否為正數且只有 1 個 bit 為 1,!(__builtin_ctz(num) & 0x1)
則是在判斷右邊0的數量是否為偶數個.不同的實作
(num & (num - 1))==0
的部分可以使用!(__builtin_popcount(num) ^ 1)
來代替,原本想用__builtin_clz(num)
來代替num > 0
,但會因為 undefined behavior噴 compiler error.避免說「噴 compiler error」這樣不精準的話,因為
你可額外加上
num > 0
的檢查條件,置於 clz 呼叫之前- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →練習 LeetCode 1009. Complement of Base 10 Integer
Memory Usage : 6.1 MB, less than 40.99% of …
練習 LeetCode 41. First Missing Positive
Memory Usage : 9.9 MB, less than 49.44% of …
3. __builtin_popcount
針對 LeetCode 1342. Number of Steps to Reduce a Number to Zero,我們可運用 gcc 內建函式實作,假設 int 寬度為 32 位元,程式碼列表如下:
32 bits 內的 bit = 1 的數量等同要執行 subtract 的次數,因此可以很容易之道
AAA
的答案應為__builtin_popcount(num)
,執行完__builtin_popcount(num)
後我們還需要向右移動 1 個 bit,透過__builtin_clz(num)
我們可以找到最左邊的 1 在哪個位置,找到後用31-__builtin_clz(num)
就可以知道應該向右 shift 幾次,所以BBB
為__builtin_clz(num)
.4. 64-bit GCD
考慮以下 64-bit GCD (greatest common divisor, 最大公因數) 求值函式:
改寫為以下等價實作:
gcd(u,v) = 2*gcd(u/2,v/2)
gcd(u,v) = gcd(u/2,v)
gcd(u,v) = gcd(u,v/2)
XXX = v
YYY = u << shift
.透過 __builtin_ctz 改寫
注意到下面的實驗中會將 quiz3 中題目的作法命名為 fast gcd,使用 __builtin_ctz 調整後的版本則稱為 faster gcd 以方便解釋。
前面的
for (shift = 0; !((u | v) & 1); shift++)
迴圈可以使用 __builtin_ctz 來改寫為如下:5. bit array
在影像處理中,bit array (也稱 bitset) 廣泛使用,考慮以下程式碼
可用 clz 改寫為效率更高且等價的程式碼:
看向原 Code 第 9 行,目的是要從最右邊的 bit 開始 check 是否為 1,下面改寫的版本把 for 改成 while,
bitset & -bitset
是把bitset
與-bitset
的 2 的補數做 & ,這樣即可得到最右邊 bit 數為 1 且其他 bits 皆為 0 的 bitmap,最後第 12 行是用來將最右邊 1 改為 0,這樣下次__builtin_ctzll(bitset)
就不會找到錯誤的 bit .