SIMD 擴展(SIMD extension)
想像一輛車出廠時配普通引擎,後來廠商賣一套外掛渦輪套件,為需要的人加馬力——但沒裝套件的車照樣開得好好的,只是上高速公路慢一點。SIMD 擴展就是 CPU 指令集的渦輪套件:在一個普通的純量指令集上加一束額外指令與寬暫存器,讓想要資料層級平行的程式能用,而舊程式原封不動照常運作。
這些擴展之所以出現,是因為日常 CPU(不只是超級電腦)開始做大量陣列工作——解碼影片、混合音訊、繪製影像、跑遊戲物理。於是廠商把向量風格的指令嫁接到主流指令集上。在 x86,這一族跨越數十年成長:MMX,接著 SSE(128 位元),接著 AVX(256 位元),接著 AVX-512(512 位元),每一個都是加上更寬暫存器與更多運算的新擴展。在 ARM,對應的是 NEON 與可擴展的 SVE。每個擴展定義新的暫存器名稱(x86 的 XMM、YMM、ZMM)與新指令,把好幾個數字塞進一個暫存器、步調一致地對它們運算,正是 SIMD 構想。
幾個誠實且重要的微妙之處。第一,SIMD 擴展是架構的一部分——軟體看到的契約——所以為 AVX-512 編譯的二進位檔,在缺那些指令的舊晶片上會當機或拒跑;程式必須在執行期檢查 CPU 支援哪些擴展,或附上多個版本。第二,有硬體不等於用得到:運算存在,但你的迴圈只有在被寫成或編譯成餵那些寬車道時才受益(見自動向量化)。第三,激進使用最寬的單元(AVX-512)在歷史上曾讓某些晶片調降時脈以守住功耗上限,所以越寬不一定是乾淨的勝利——這是個真實的提醒:更寬的 SIMD 是工具,不是保證。
一個為 AVX2 建置的程式用 256 位元的 YMM 暫存器每條指令加八個浮點數。把同一個二進位檔拿到只有 SSE(128 位元)的 2008 年 CPU 上跑,就會撞上非法指令錯誤——那裡根本不存在 AVX 的運算碼,這就是為什麼軟體會在使用前探測 CPU 功能旗標(CPUID)。
SIMD 擴展在純量指令集上加寬暫存器與指令;要用它們,晶片必須真的支援那個擴展。
SIMD 擴展是指令集架構的一部分,所以它打破二進位相容:AVX-512 的二進位檔在沒有 AVX-512 的晶片上跑不動。而且光有那個單元並不會讓你的程式變快——程式必須真的被向量化才用得到。