強擴展與弱擴展(strong vs weak scaling)
對一個平行程式,你可以誠實地問兩個問題,而它們有不同的答案。第一個:「我有一件固定的工作——若我投入更多工人,它能多快完成?」第二個:「若我想在相同時間內做更大的工作,需要多多少工人?」這就是強擴展與弱擴展,混淆兩者,正是人們在程式「停止擴展」時感到意外的原因,而其實它的行為恰如定律所預測。
強擴展固定總問題規模、增加處理器數 p。指標是加速比 S(p) = T(1) / T(p),理想上等於 p,以及平行效率 E(p) = S(p) / p,理想上 100%。強擴展是艱難的局面:你加處理器時,每一個分到的工作縮小,而固定成本(通訊、同步、序列比例)不縮,故效率下降——終究每個處理器做的實活少到開銷主宰一切。阿姆達爾定律正是強擴展的天花板。弱擴展則讓問題規模隨 p 等比增長,使每個處理器的工作量維持不變。指標是當你把問題與機器一起放大時,執行時間是否大致保持平坦。弱擴展是較仁慈的局面——古斯塔夫森「更大的機器用於更大的問題」的觀察住在這裡——許多真實模擬即使強擴展很差,仍能弱擴展到巨大的核心數。
哪一個要緊,取決於你的目標。若你有一個太慢的固定模擬,你在乎強擴展,且你會撞上由序列比例與通訊立起的牆。若你想要更高解析度或更大的領域、並願意用等比更大的機器,你在乎弱擴展,它通常寬容得多。報一個加速比卻不說你量的是哪種擴展,是沒有意義的——一段程式在同一台機器上,可以展現漂亮的弱擴展曲線與令人失望的強擴展曲線,而兩者都可以是誠實的。
一個在固定 100 公里網格上的天氣模型做強擴展:1 核耗 1000 秒,100 核耗 14 秒(效率 71%),但 1000 核只耗 3 秒(效率 33%),因為此時通訊主宰。同一模型做弱擴展——加核心時就加細網格,使每個核心永遠擁有相同數目的格子——能把執行時間從 100 核一路到 100000 核都維持在約 14 秒,因為每個核心的工作量從不改變。
強:固定問題、更多核心 -> 效率下降。弱:問題隨核心增長 -> 執行時間平坦。
效率超過 100%(超線性加速)是真的,但通常是快取效應:拆到更多核心後,每個核心那一片終於放得進快取,故每核速度躍升。這不違反任何定律——只是表示你的單核基準被快取失誤拖累了。