併發設計練習題 (Practice - Designing Concurrent Code)


Question 1 - 三種劃分策略 [recall]

執行緒間劃分工作有哪三大策略?各自的前提與適用情境為何?


Question 2 - 快取乒乓 [recall]

多條執行緒在迴圈中對同一個 std::atomic 計數器做 fetch_add,即使用了 memory_order_relaxed 還是很慢。為什麼?


Question 3 - 偽共享與 C++17 工具 [recall]

什麼是偽共享 (false sharing)?C++17 的 <new> 提供哪兩個常數,各自用途為何?


Question 4 - Amdahl 定律 [recall]

寫出 Amdahl 定律的公式。若程式的串行部分占 1/3,處理器無限多時最多加速幾倍?


Question 5 - 平行演算法的異常安全改造 [recall]

std::thread 版的 parallel_accumulate(代碼 8.2)有哪些異常漏洞?書中的三步改造是什麼?


Question 6 - parallel_find 的提前結束 [recall]

平行版 std::find 如何讓其他執行緒在找到後停止?若要找的值不在範圍內,直接 future.get() 會發生什麼事?


Question 7 - 矩陣乘法的劃分選擇 [application]

你要在 100 個處理器上平行計算兩個 1,000×1,000(row-major)矩陣的乘積。按行劃分與按塊劃分,每執行緒各需讀取多少元素?該選哪個?


Question 8 - I/O 受限的掃描器 [application]

病毒掃描器以管線劃分:一條執行緒搜檔案系統丟入佇列,一條執行緒取出並掃描。掃描執行緒常因讀磁碟而閒置,CPU 使用率很低。你會怎麼改?要注意什麼?


Question 9 - partial_sum 兩種平行法比較 [analysis]

比較平行版 std::partial_sum 的「逐段傳播」與「barrier + 2 的冪距離」兩種實作:總工作量、步數、適用硬體、異常安全性。


Question 10 - parallel_find 的設計取捨 [analysis]

分析平行版 std::find 的三個設計決策:(a) 為何必須中斷其他執行緒?(b) 為何選 std::promise 而非 std::packaged_task?(c) 它與 std::find 的語義有何差異?