sysprog2020
目的: 檢驗學員對 Arm 處理器及 dynamic programming 的認知
1
針對「灰色」,美式英語常用 "gray" 拼法,英式英語則慣用 "grey" 拼法,兩者同義。
給定每個像素 (pixel) 為 32-bit 的 RGBA 的位元圖 (bitmap),RGBA 代表紅綠藍三原色的首字母,Alpha 值則表示顏色的透明度/不透明度,其轉換為灰階影像 (gray scale) 的函式為:
人類視網膜包含三類錐形對光敏感的細胞,分別對不同波長範圍的光有反應:
上圖中的縱軸代表人眼對某對應波長的光的敏感度。其中 1 Å (埃) = 米 = 0.1 nm [出處]
人眼吸收綠色比其他顏色敏感,也可說人眼最容易捕捉到綠色,所以當影像變成灰階時,僅僅將紅色、綠色、藍色加總取平均,不足以反映出人眼所見。常見的方法是將 ,這三個除數的總和為 256
(即 ),可使除法變簡單 (等同於右移 8 位元)。
如果我們將所有的運算都建立表格,於是
16 MB; 表格太大
如果先計算針對「乘上 0.299」一類的運算,計算後建立表格呢?
降到 32 KB 以內; cache friendly
接著嘗試使用 NEON 指令集加速。將 RGB 三色的權重存入 r3, r4, r5 等暫存器。
vdup.8
(Vector Duplicate),分別複製到大小為 8 bit 的 NEON register d0 - d2
vld4.8
(Vector Load),載入 pixel 的資料到 4 個 8-bit 的 NEON register d4-d7,其中那個 4
為 interleave,因為我們有 ARGB,所以 gap = 4。
再來就是計算 weighted average。可用 Vector Multiply 和 Vector Multiply Accumulate 指令:
將值除以 256 就是我們要的灰階值。
vrshrn
(Vector Shift Right by immediate value)
vrshrn.u16 d4, q10, #8
最後儲存結果。
vst
(Vector Store)
vst4.8 {d4-d7}, [r3]!
效能評比如下: (對照 v0
和 v4
)
從這張表即可理解,使用 NEON 指令加速只用原本 4.6% 的時間即可完成 RGBA 轉灰階的處理。
Neon Intrinsics 允許我們避免直接撰寫組合語言,而是有如 C 函式呼叫,例如 vmull.u8
和 vmlal.u8
分別對應以下 intrinsics: (提示: 在 Neon Intrinsics 網頁搜尋 NEON intrinsics 可獲得更詳盡的描述)
考慮以下使用 float
來保存像素的程式碼:
函式 to_rgb
可將原本透過連續的 float
空間保存的資料轉為 RGB 像素,每個像素佔用 3 個位元組,即 24 位元。針對 Aarch64 (Arm 64-bit) 架構 (假設為 little-endian),下方的程式碼則可將 RGB 轉換為灰階:
請補完程式碼,使上述程式碼得以符合預期地運作。
作答區
OFFSET1 = ?
(a)
(-4)(b)
(-2)(c)
(-1)(d)
0 (o)(e)
1(f)
2(g)
4OFFSET2 = ?
(a)
(-4)(b)
(-2)(c)
(-1)(d)
0(e)
1(f)
2(g)
4 (o)延伸問題:
2
LeetCode 1617. Count Subtrees With Max Distance Between Cities 給定 個城市,編號為從 到 ,再給予一個大小為 的陣列 edges
,其中 表示城市 和 之間存在雙向邊。題目保證任意城市之間有唯一的路徑,也就是說所有城市構成一棵樹 (tree)。
上圖的連通關係為:
一棵子樹 (subtree) 是上述所有城市的子集,在子集中,任意城市間可透過子集的其他城市和邊到達。兩個子樹被認為不一樣的條件是,至少有個城市在其中一棵子樹中存在,卻又不存在於另一棵子樹中。
給定 範圍介於從 到 ,請你找出城市間最大距離恰好為 的所有子樹數目。請你回傳一個大小為 的陣列,其中第 個元素(下標從 1 開始)是城市間最大距離恰好等於 的子樹數目。
兩個城市間距離定義是,它們之間需要經過的邊的數目。
第一組輸入:
預期輸出:
既然 ,於是輸出的陣列會有 3 個元素
- 子樹
{1,2}
,{2,3}
和{2,4}
最大距離都為 1- 子樹
{1,2,3}
,{1,2,4}
,{2,3,4}
和{1,2,3,4}
最大距離都為2
- 不存在城市間最大距離為
3
的子樹。
第二組輸入:
預期輸出:
既然 ,於是輸出的陣列只存在 1 個元素,且題目已保證任意城市之間只有唯一的路徑
第三組輸入:
預期輸出:
既然 ,於是輸出的陣列會有 2 個元素
- 子樹
{1,2}
和{2,3}
最大距離都為1
- 子樹
{1,2,3}
最大距離為2
限制:
思路:
在圖論中,環是一條只有第一個和最後一個頂點重複的非空路徑
- 不具備環的圖被稱作無環圖
- 不具備有向環的有向圖被稱做有向無環圖 (DAG,directed acyclic graph)
- 無環的連通圖被稱作樹
以下程式碼是針對 LeetCode 1617. Count Subtrees With Max Distance Between Cities 提出可能的解法:
參考資訊
請補完程式碼,使上述程式碼得以符合預期地運作。
作答區
COND1 = ?
(a)
conn_nxt == ctmp
(b)
conn_nxt != ctmp
(c)
conn_nxt >= ctmp
(d)
conn_nxt
COND2 = ?
(a)
ctmp
(b)
!ctmp
(c)
~ctmp & S
(d)
ctmp & ~S
(e)
ctmp ^ S
ITER = ?
(a)
++ret
(b)
--ret
(c)
ret++
(d)
ret--
(e)
ret
延伸問題: