首页 >后端开发 >C++ >如何使用SIMD指令实现高性能的atoi函数?

如何使用SIMD指令实现高性能的atoi函数?

DDD
DDD原创
2024-12-01 08:05:16717浏览

How Can SIMD Instructions Be Used to Implement a High-Performance atoi Function?

atoi 函数的 SIMD 实现

简介:

atoi 是一个函数,将整数到其数值的字符串表示形式。本文探讨如何使用 SIMD 指令实现 atoi。

算法:

  1. 用值 10^0, 10^1, .. 初始化向量 V ., 10^N.
  2. 将输入字符串中的每个字符转换为整数并存储在向量 S。
  3. 将 S 的每个元素乘以 V 的相应元素,并将结果存储在新的向量 P 中。
  4. 对 P 进行一系列水平加法和乘法以获得最终结果结果。

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             /* if first char is invalid return 0 - prevent processing empty string - 0 is still in EAX */
   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 */

SIMD 实现的优点:

  • 提高了处理大数字字符串的性能。
  • 适用于 x86 和 x86-64
  • 支持多个同时 atoi 操作。

限制:

  • 需要特定的 SSE4.2 指令。
  • 可能不适合小弦或混合弦

结论:

与传统方法相比,atoi 的 SIMD 实现在处理大整数字符串方面提供了显着的加速。该算法针对 x86 和 x86-64 架构进行了优化,可以并行执行多个 atoi 操作。虽然它在处理小字符串和混合字符字符串方面存在局限性,但它仍然是数值计算的一种有价值的技术。

以上是如何使用SIMD指令实现高性能的atoi函数?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn