並行與平行的差別
想像一位咖啡師接了三筆咖啡訂單。他啟動義式咖啡機,趁機器萃取濃縮咖啡的時候,去幫第二筆訂單打奶泡,再幫第三筆結帳,一個人、來回切換、讓三杯飲料都在往前推進。這就是並行(concurrency):透過交錯處理,同時應付多個任務。再想像三位咖啡師,每人在同一瞬間各做一杯。這就是平行(parallelism):真的同時在做多個任務。對初學者最關鍵的一點是:這是兩個不同的概念,一個講的是結構(應付多件事),另一個講的是執行(真的同時做多件事)。
用計算的術語來說:並行指的是好幾個任務在同一段期間內都在進行中,但在單一核心上,CPU 其實一次只跑一個,只是在它們之間快速切換。從外面看起來像是同時進行,就像雜耍者用兩隻手讓好幾顆球同時在空中。平行則指任務真的在同一瞬間執行,這需要不只一個執行單元,通常是好幾個 CPU 核心。你可以有並行而沒有平行(單核心、多個交錯的執行緒),而且通常要先在程式設計上做到並行,平行才幫得上忙。一個程式若被組織成一些獨立的任務,它就是並行的;只有當硬體允許其中好幾個任務在同一刻同時推進時,它才真的在平行執行。
為什麼要分清楚?因為它們解決不同的問題、各有不同的極限。並行能改善反應性,並讓你把等待(例如等磁碟或網路)和有用的工作重疊起來,即使只有一個核心也行。平行能提升運算密集型工作的純吞吐量,但只能提升到你擁有的核心數為止,而且只對能被分割的工作有效。混淆這兩者會帶來錯誤的期待,例如以為只要加上執行緒程式就會快一倍,但機器其實只有一個核心,或者那項任務根本無法分割。
在單核心筆電上並行下載十個檔案是真的有用:當一個下載在等網路時,CPU 切去處理另一個,於是整體等待時間縮短。但把十億個數字加總,在單核心上光靠並行不會變快,它需要平行(好幾個核心各加總一塊)才能真正加速。
並行=應付很多件事;平行=同時做很多件事。
並行是程式「如何被組織」的性質;平行是它「如何在硬體上執行」的性質。你可以只有其中一個,而且單核心上的並行永遠不會增加真正同時的運算。