迭代式 MRI 重建 練習題 (Practice - MRI Background and the Iterative Reconstruction Problem)


Question 1 - MRI 兩階段與 k-space [recall]

MRI 流程分哪兩個階段?「k-space」是什麼域,掃描器在其中如何取樣?

Question 2 - Cartesian 為何能用 inverse FFT [recall]

為什麼 Cartesian 掃描軌跡的資料可以直接用 inverse FFT 重建?non-Cartesian 軌跡(如 spiral)為何不行,改採什麼策略?

Question 3 - 為何用 CG 而非直接矩陣求逆 [recall]

逆問題 ρ = (FᴴF + λWᴴW)⁻¹ FᴴD 表面只是矩陣相乘與求逆,為何不能用 Gaussian elimination 直接解?改用什麼方法?

Question 4 - FHD vs Q,為何只平行化 FHD [recall]

FHD 與 Q 有何關係?為何本章選擇平行化 FHD,而把 Q 與 CG solver 排除在外?

Question 5 - Sequential FHD 的迴圈結構與依賴 [recall]

Fig. 17.4 的循序 FHD 為雙重迴圈(外 m、內 n)。哪些 iteration 可平行?存在什麼依賴?它有哪兩個效能瓶頸?

Question 6 - 第一版 scatter kernel 為何需要 atomicAdd [recall]

Fig. 17.5 第一版 FHD kernel 把外迴圈(m)映射到 thread。為何內迴圈必須用 global-memory atomicAdd?為何不能像 Ch.9 直方圖那樣用 shared-memory privatization 解決?

Question 7 - Loop Fission 與 Loop Interchange [recall]

要把 FHD 轉成 gather,必須做 loop interchange,但為何得先做 loop fission?fission 改變了兩部分的執行順序,為何結果仍正確?

Question 8 - Register Promotion 與 kx[m] 的差異 [recall]

在 gather kernel(Fig. 17.10)中,哪些陣列元素可提升到 register?為何 x[n] 可以但 kx[m] 不行?

Question 9 - Constant Memory:Broadcast 與 Chunking [recall]

為何 k-space 陣列 kx/ky/kz 特別適合 constant memory?constant memory 有何容量限制,如何在 host 端解決?

Question 10 - Hardware 三角函數與精度驗證 [recall]

__sin()/__cos()sin()/cos() 有何差異?換用硬體版後如何驗證精度沒有壞掉?

Question 11 - 計算各階段 OP/B [application]

gather kernel 內層迴圈每次迭代有 13 個浮點運算。(a) 全走 global memory(14 accesses)的 OP/B?(b) 把 5 個元素放 register(7 accesses)後?(c) 再把 k-space 放 constant memory(剩 2 個 global access)後?

Question 12 - Grid/Block 配置與 chunking memcpy 大小 [application]

(a) 128³ 影像的 gather kernel,block = 1024 threads,grid 幾個 block?(b) M = 1,000,000 樣本的 cmpMu 用同樣 block size,grid 幾個?(c) 改用 array-of-structures 後,單次 cudaMemcpyToSymbol 搬移的 byte 數由 4·CHUNK_SIZE 變成多少?為什麼?

Question 13 - Working Set 與 Constant Cache Thrashing 計算 [application]

某裝置每 block 1024 threads、每 SM 常駐 2 個 block,k-space 存於三個分離陣列(kx/ky/kz)。(a) 一個 SM 同時有幾個 warp?(b) 每 warp 每迭代需 3 條 cache line,最壞情況 working set 幾條?(c) 若該裝置 constant cache 只有 32 條 line,會發生什麼?如何解決?

Question 14 - 三種 Kernel 選項:為何 Gather 最佳 [analysis]

Fig. 17.6 的第二個迴圈有三種 kernel 設計:①thread=內迴圈 iteration、②thread=外迴圈(m)、③thread=輸出 voxel(n)。從 thread 數量、是否需 atomics、平行度三方面比較,並說明為何選 ③。

Question 15 - AoS vs SoA:與 Coalescing 規則為何相反 [analysis]

在 global memory 中,把 struct 的欄位拆成多個陣列(SoA)才能 coalesce;但本章卻把 k-space 從三個陣列(SoA)改成 array-of-structures(AoS)。為何兩處結論相反?

Question 16 - 10× 加速後的 Amdahl 反噬與 HW Trig 的 OP/B 弔詭 [analysis]

(a) 從基礎版到最佳化版約 10× 加速後,為何 FHD 在整體重建中的占比反而由 ~100% 降到 ~50%?這說明什麼定律?(b) 換用 HW trig 反而把 OP/B 推向 worst-case 0.25,為何整體仍更快?