Rumah > pembangunan bahagian belakang > C++ > Bagaimanakah Arahan SIMD Boleh Digunakan untuk Melaksanakan Fungsi atoi Berprestasi Tinggi?

Bagaimanakah Arahan SIMD Boleh Digunakan untuk Melaksanakan Fungsi atoi Berprestasi Tinggi?

DDD
Lepaskan: 2024-12-01 08:05:16
asal
722 orang telah melayarinya

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

Pelaksanaan SIMD bagi Fungsi atoi

Pengenalan:

atoi ialah fungsi yang menukar perwakilan rentetan integer kepada nilai berangkanya. Artikel ini meneroka cara melaksanakan atoi menggunakan arahan SIMD.

Algoritma:

  1. Memulakan vektor V dengan nilai 10^0, 10^1, .. ., 10^N.
  2. Tukar setiap aksara dalam rentetan input kepada integer dan simpannya dalam vektor S.
  3. Darab setiap unsur S dengan unsur V yang sepadan dan simpan hasilnya dalam vektor baharu P.
  4. Lakukan satu siri tambah dan darab mendatar pada P untuk mendapatkan yang terakhir hasil.

Pelaksanaan dalam GNU Pemasang:

.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
Salin selepas log masuk
.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 */
Salin selepas log masuk

Kelebihan Pelaksanaan SIMD:

  • Peningkatan prestasi untuk memproses rentetan nombor yang besar.
  • Boleh untuk x86 dan x86-64 seni bina.
  • Menyokong berbilang operasi atoi serentak.

Penghadan:

  • Memerlukan arahan SSE4.2 khusus.
  • Mungkin tidak sesuai untuk tali kecil atau tali bercampur aksara.

Kesimpulan:

Pelaksanaan SIMD atoi menawarkan kelajuan yang ketara untuk memproses rentetan integer yang besar berbanding kaedah tradisional. Algoritma ini dioptimumkan untuk seni bina x86 dan x86-64 dan boleh melaksanakan berbilang operasi atoi secara selari. Walaupun ia mempunyai had dalam mengendalikan rentetan aksara kecil dan bercampur, ia kekal sebagai teknik yang berharga untuk pengiraan berangka.

Atas ialah kandungan terperinci Bagaimanakah Arahan SIMD Boleh Digunakan untuk Melaksanakan Fungsi atoi Berprestasi Tinggi?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan