向量長度(vector length)
假設你有個一按印八個信封的印章,但今天的工作恰好是二十三個信封。二十三除以八除不盡:按兩次蓋了十六個,第三次再蓋八個——但你絕不能把第三次的最後一個也蓋下去,否則會弄髒桌上一個空白信封。向量長度就是那個旋鈕,告訴機器「這一次只有前 N 條車道是真的,其餘忽略」。這是固定寬度的向量單元處理「大小不是車道數整齊倍數」的陣列的方法。
在真正的向量處理器上有一個特別的向量長度暫存器。一個對譬如 1000 個元素的陣列、用 64 元素向量暫存器的迴圈,分塊跑:把長度設為 64 處理第 0 到 63 個元素,再來 64 到 127,依此類推;最後一塊只剩 1000 減 960 等於 40 個元素,於是你把長度設成 40,硬體就只對那些車道動手,其餘 24 條原封不動。這種「條帶開採」(strip-mining)把任意長度的陣列變成一連串滿寬度的處理外加一個短尾巴,既不會越界破壞,也不會浪費寫入。
向量長度也是現代「長度無關」向量指令集背後較乾淨的構想。在 RISC-V 的向量擴展或 ARM 的 SVE 裡,程式不寫死寬度;它問硬體「你一次能做幾個元素?」再依那個數量做迴圈。於是同一個二進位檔在向量為 128 位元的小晶片與 512 位元的大晶片上都正確執行,只是各自迴圈不同的次數——程式寫一次就能擴展。誠實的提醒:短尾塊會浪費一些車道,所以很短的陣列得不到什麼好處,當資料極小時迴圈設定的開銷反而可能主導。
用 64 寬的向量把兩個各 1000 個浮點數的陣列相加:十五次滿載(15 x 64 = 960 個元素)外加一次把向量長度設為 40 的尾巴。尾巴那一趟只碰 64 條車道中的 40 條,所以第 1000 個及之後從不會被寫入。
向量長度讓固定寬度的單元安全處理「不是車道數整齊倍數」的陣列。
長度無關的向量指令集(RISC-V V、ARM SVE)與固定寬度的 SIMD(AVX)不一樣。長度無關的程式一個二進位檔就能跨向量寬度擴展;固定寬度的 SIMD 把寬度烤死,要用更寬的單元就必須重新編譯。