如何使用SIMD 實作atoi
在本文中,我們將探討實作atoi 函數的演算法,該函數將字串表示形式轉換為使用單指令多重資料(SIMD) 指令將整數轉換為其數值。透過使用 SIMD,我們可以透過並行處理多個元素來實現顯著的效能改進。
演算法
建議的演算法由下列步驟組成:
實現注意事項
在SIMD 程式碼中實現此演算法時,我們可以實現此演算法利用SIMD 指令固有的並行性來同時處理多個數字。程式碼應針對所使用的特定 SIMD 指令集(例如 SSE4.2、AVX2)進行最佳化。
潛在最佳化:可以進一步最佳化此演算法不需要單獨的迴圈來將有效數字乘以 10 的冪次方。這可以透過使用稱為“向量索引”的技術來實現與融合乘加。 「這種技術允許我們在一條指令中執行索引和乘法,從而提高效能。
替代建議正如Peter Cordes 在評論中所建議的,最後兩個加法異或指令的替代方法是使用imul(整數乘法)指令。的範例實作與Intel 合作的GNU組合程式語法:
結論
.intel_syntax noprefix .data .align 64 ddqDigitRange: .byte '0','9',0,0,0,0,0,0,0,0,0,0,0,0,0,0 ddqShuffleMask:.byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 ddqFactor1: .word 1,10,100,1000, 1,10,100,1000 ddqFactor2: .long 1,10000,100000000,0 .text _start: mov esi, lpInputNumberString /* (**A**) indicate negative number in EDX */ mov eax, -1 xor ecx, ecx xor edx, edx mov bl, byte ptr [esi] cmp bl, '-' cmove edx, eax cmp bl, '+' cmove ecx, eax sub esi, edx sub esi, ecx /* (**B**)remove leading zeros */ xor eax,eax /* return value ZERO */ remove_leading_zeros: inc esi cmp byte ptr [esi-1], '0' /* skip leading zeros */ je remove_leading_zeros cmp byte ptr [esi-1], 0 /* catch empty string/number */ je FINISH dec esi /* check for valid digit-chars and invert from front to back */ pxor xmm2, xmm2 movdqa xmm0, xmmword ptr [ddqDigitRange] movdqu xmm1, xmmword ptr [esi] pcmpistri xmm0, xmm1, 0b00010100 /* (**C**) iim8=Unsigned bytes, Ranges, Negative Polarity(-), returns strlen() in ECX */ jo FINISH /* if first char is invalid return 0 - prevent processing empty string - 0 is still in EAX */ mov al , '0' /* value to subtract from chars */ sub ecx, 16 /* len-16=negative to zero for shuffle mask */ movd xmm0, ecx pshufb xmm0, xmm2 /* broadcast CL to all 16 BYTEs */ paddb xmm0, xmmword ptr [ddqShuffleMask] /* Generate permute mask for PSHUFB - all bytes < 0 have highest bit set means place gets zeroed */ pshufb xmm1, xmm0 /* (**D**) permute - now from highest to lowest BYTE are factors 10^0, 10^1, 10^2, ... */ movd xmm0, eax /* AL='0' from above */ pshufb xmm0, xmm2 /* broadcast AL to XMM0 */ psubusb xmm1, xmm0 /* (**1**) */ movdqa xmm0, xmm1 punpcklbw xmm0, xmm2 /* (**2**) */ punpckhbw xmm1, xmm2 pmaddwd xmm0, xmmword ptr [ddqFactor1] /* (**3**) */ pmaddwd xmm1, xmmword ptr [ddqFactor1] phaddd xmm0, xmm1 /* (**4**) */ pmulld xmm0, xmmword ptr [ddqFactor2] /* (**5**) */ pshufd xmm1, xmm0, 0b11101110 /* (**6**) */ paddd xmm0, xmm1 pshufd xmm1, xmm0, 0b01010101 /* (**7**) */ paddd xmm0, xmm1 movd eax, xmm0 /* negate if negative number */ add eax, edx /* (**8**) */ xor eax, edx FINISH: /* EAX is return (u)int value */
atoi 函數的這種最佳化的 SIMD 實作可以在處理大量數值資料時顯著提高效能。透過利用 SIMD 指令的平行處理能力,我們可以實現更快的執行時間並更有效地處理數值計算。
以上是如何使用SIMD指令優化atoi功能?的詳細內容。更多資訊請關注PHP中文網其他相關文章!