資料平行(data parallelism)
想像有一千份考卷,全都要套用同一份評分標準。最快的批改方式,是把整疊分成十堆,每堆交給十位助教其中一位。每位助教做的工作完全一樣,就是套用評分標準,只是改的是不同的考卷。資料平行就是把這個想法放進程式裡:你拿一大批資料,切成好幾塊,對每一塊在同一時間執行相同的操作,一塊交給一個執行緒或核心。
具體來說,資料平行(也稱為資料分解的觀點)把資料切開,把工作複製。如果你想把一個一百萬個數字的陣列每個元素都加 1,你可以把前面二十五萬個元素交給執行緒 0、下一個二十五萬交給執行緒 1,依此類推分到四個核心上;每個執行緒對自己那一塊跑相同的加法迴圈。操作到處都一樣,只有每個執行緒碰到的資料不同。每當你有一大批規律、均勻的資料,而操作又能獨立地套用在每個元素上時,這就是最自然的作法,這也正是繪圖處理器(GPU)的設計核心,因為它要對數百萬個像素跑同一段著色器。
難處在於,資料平行只有在切出來的各塊真正獨立時才出色,也就是計算某一塊不需要用到另一塊的結果。一旦元素彼此相依(許多物理模擬就是如此),執行緒之間就必須通訊或同步,乾淨俐落的加速就被侵蝕。它同樣受阿姆達爾定律限制:任何前置設定、任何最後的合併步驟、任何切塊大小不均(負載不平衡)都會吃掉所能得到的加速。可以拿它和任務平行對照:任務平行裡的執行緒是做不同的工作,而非對不同資料做相同的工作。
把彩色照片轉成灰階天生就是資料平行:每個像素的新值只取決於它自己的紅、綠、藍三色,所以你可以把四分之一的像素分給四個執行緒中的一個,它們同時跑完全相同的「彩色轉灰階」公式,彼此完全不需要溝通。
相同的操作、不同的資料切片,把資料切開、把工作複製。
資料平行只有在各切片彼此獨立時才見效。如果計算一個切片需要另一個切片的結果,執行緒就必須同步,那種通訊可能把加速抵消掉。