近期為優化字串處理,嘗試用 SSE2 實現 128-bit 邏輯位移,卻發現指令集藏著驚人缺口:SSE2 根本沒有 128-bit 位元級位移指令。
這些指令皆為「分組位移」,而非整體 128-bit 位移。
PSLLDQ(Packed Shift Left Logical Double Quadword)乍看支援 128-bit,實際上最小位移單位為 8 位(1 Byte),且立即數限制為 imm8,無法用暫存器指定位移量,極大限制動態位移場景。
查閱 Intel 手冊發現:PSLLQ 作用於 64-bit 暫存器(MMX)時支援 0~63 位位移,但作用於 128-bit XMM 暫存器時,**最大僅能位移 15 位**(文件標註 COUNT_MAX=15)。這導致無法用「高位用 PSLLDQ 移 Byte、低位用 PSLLQ 移殘餘」的組合拳,因為 PSLLQ 根本移不動超過 15 位的殘餘。
Google 搜尋 128 bit shift 發現大量開發者踩坑。Intel 論壇討論串 Missing instruction in SSE: PSLLDQ with bit shift amount? 中,Intel 工程師確認:SSE2 確實未實作 128-bit 位元位移,建議改用 PSHUFD + PSLLDQ + PSRLD 組合模擬,但效能與程式複雜度雙雙上升。
無奈下只能退而求其次:將 128-bit 拆為高低兩個 64-bit,分別用 PSLLQ/PSRLQ 處理,再用 POR 合併。雖需額外分支判斷與資料搬移,但在現有指令集下是相對高效的通用解法。完整組合語言實作可參考 Agner Fog 的最佳化手冊或 Intel Intrinsics Guide。
SSE2 的 128-bit 位移缺口,暴露了早期 SIMD 設計「僅支援 64-bit 粒度運算」的歷史包袱。直到 AVX-512 引入 VPSLLVQ(變量位移)才徹底解決。在此之前,開發者只能自行組合指令繞過這顆「智商稅」地雷。