平行演算法練習題 (Practice - Parallel Algorithms)


Question 1 - 平行演算法簽名 [recall]

C++17 的平行演算法與既有單執行緒版本在函式簽名上有何差異?指定 std::execution::par 是否保證多執行緒執行?


Question 2 - 三種策略與標頭檔 [recall]

請列出三個標準執行策略類別與對應的策略物件,它們定義在哪個標頭檔?開發者可以自行建構或自訂執行策略嗎?


Question 3 - 異常行為 [recall]

std::for_eachseq, v.begin(), v.end(), ff 拋出異常且未捕獲,會發生什麼事?與不帶執行策略的版本有何不同?


Question 4 - par_unseq 的同步限制 [recall]

使用 std::execution::par_unseq 時,對迭代器、相關值與可呼叫物件有什麼同步方面的限制?為什麼?


Question 5 - 迭代器類別提升 [recall]

普通版 std::copy 接受輸入/輸出迭代器,帶執行策略的重載對迭代器類別的要求是什麼?這個提升為何對平行化重要?


Question 6 - accumulate vs reduce [recall]

為什麼 std::accumulate 沒有平行版本?想平行做累加該用什麼?使用時要注意什麼前提?


Question 7 - 平行填充計數器 [application]

同事寫了 std::for_eachpar, v.begin(), v.end(), [&](int& x){ x = ++count; });(countint。這段程式碼有什麼問題?庫實測只用了單執行緒,還算有問題嗎?該如何修正?


Question 8 - 策略選擇 [application]

你要對 std::vector<X> 的每個元素呼叫 x.increment(),而 X::increment() 內部以 std::mutex 保護資料(代碼 10.1 的類別)。應選 par 還是 par_unseq?若想改用 par_unseq,程式要怎麼重構?


Question 9 - 鎖粒度取捨 [analysis]

比較代碼 10.1(每元素內部 mutex + par)與代碼 10.2(整個容器一把 mutex + par_unseq)兩種設計:各自的優缺點?什麼情況下哪種較好?


Question 10 - transform_reduce 設計分析 [analysis]

代碼 10.3 用 std::transform_reducepar, lines.begin(), lines.end(), visit_map_type(), combine_visits(), parse_log_line) 統計每頁訪問次數。為何 combine_visits 需要 4 個 operator( 重載而不能用 Lambda?合併兩個 map 的重載為何先 std::swap 讓較小者當 rhs?