[Программирование, Assembler] Перевод числа в строку с помощью SIMD + FPU

Автор Сообщение
news_bot ®

Стаж: 6 лет 9 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
13-Фев-2021 20:31

Вариант конвертирования double / real8 в строку посредством с SIMD использованием FPU в качестве вспомогательного средства. Применение FPU вызвано желанием получить 16 значащих цифр.В соответствии с x64 software conventions будем считать что число подлежащие конвертированию расположено в XMM0.Будем использовать x64 битный код при x32 битной адресации. Такой способ адресации позволяет использовать преимущества обоих диалектов.Будем использовать недокументированное соглашение о передаче / возврате из функции множественных параметров. Соглашение абсолютно зеркально соглашению x64 software conventions за тем исключением что описывает правила размещения параметров при выходе из процедуры.
ROUND_TOWARD_ZERO            equ 11b
SIGNIFICANT_BIT_RESET        equ 3Fh
NUMBER_OF_SIGNIFICANT_DIGITS equ 40E00000h
LCW          equ word
LIExp2       equ dword
LIExp10      equ dword
LSExp10      equ dword
LIUpPathNam  equ dword
LILowPathNam equ dword
LNamber      equ qword
LMulExp2     equ qword
LStX         equ tbyte
LString      equ xmmword * 2
.data
  f10m4 real4 4 dup (1.0e-4)
  f10p4 real4 4 dup (1.0e+4)
  f10m2 real4 4 dup (1.0e-2)
  f10p2 real4 4 dup (1.0e+2)
  f10m1 real4 4 dup (1.0e-1)
  f10p1 real4 4 dup (1.0e+1)
  f0001 real4 0.0, 1.0e-2, 1.0e-1, 1.0
  f0002 real4 0.0, 0.0,    1.0e+1, 1.0e+1
  f10p8 real4 1.0e+8
  NoSD  real4 7.0
  i30h  db 10h dup (30h)
  CW0   dw 0F7Fh
  CW1   dw 037Fh
  DotM  dw 652Dh
  namber   real8 -1.234567890123456e+248
.code
WinMain proc
  movd xmm0, namber
  fstcw     word ptr[esp - LCW]
  fstp     tbyte ptr[esp - LCW - LStX]
  fldcw      CW0
  movd      rax, xmm0
  mov      dword ptr[esp - LString - dword], 2D000000h
  btr       rax, SIGNIFICANT_BIT_RESET
  setnc     byte ptr[esp - LString - dword - byte]
  mov      qword ptr[esp - LCW - LStX - LNamber], rax
  shr       rax, 34h
  sub       eax, 3FFh
  mov      dword ptr[esp - LCW - LStX - LNamber - LIExp2], eax
  fldlg2
  fimul    dword ptr[esp - LCW - LStX - LNamber - LIExp2]
  fsubr    NoSD
  fistp    dword ptr[esp - LCW - LStX - LNamber - LIExp10]
  fldl2t
  fimul    dword ptr[esp - LCW - LStX - LNamber - LIExp10]
  fist     dword ptr[esp - LCW - LStX - LNamber - LIExp10 - LIExp2]
  fisub    dword ptr[esp - LCW - LStX - LNamber - LIExp10 - LIExp2]
  f2xm1
  cvtsi2ss xmm0, dword ptr[esp - LCW - LStX - LNamber - LIExp10]
  mov       eax, dword ptr[esp - LCW - LStX - LNamber - LIExp10 - LIExp2]
  add        ax, 3FFh
  shl       rax, 34h
  mov            qword ptr[esp - LCW - LStX - LNamber - LMulExp2], rax
  xor       edx, edx
  pxor     xmm1, xmm1
  comiss   xmm1, xmm0
jz @f
  shufps   xmm0, xmm0, 0
  subps    xmm1, xmm0
  maxps    xmm0, xmm1
  mulps    xmm0, xmmword ptr f0001
  roundps  xmm0, xmm0, ROUND_TOWARD_ZERO
  pshufd   xmm1, xmm0, 10010000b
  mulps    xmm1, xmmword ptr f0002
  subps    xmm0, xmm1
  cvtps2dq xmm0, xmm0
  pxor     xmm1, xmm1
  pcmpeqd  xmm1, xmm0
  packusdw xmm0, xmm0
  packuswb xmm0, xmm0
  mov       eax, 2B65h
  cmovc      ax, DotM
  movmskps  ecx, xmm1
  bsr       ecx, ecx
  lea       ecx,[ecx * 8 - 8]
  movd      edx, xmm0
  add       edx, 30303000h
  shrd      rdx, rdx, cl
  mov        dx,  ax
@@:  fmul     qword ptr[esp - LCW - LStX - LNamber - LMulExp2]
  fadd     qword ptr[esp - LCW - LStX - LNamber - LMulExp2]
  fmul     qword ptr[esp - LCW - LStX - LNamber]
  fist     dword ptr[esp - LCW - LStX - LILowPathNam - LIUpPathNam]
  fisub    dword ptr[esp - LCW - LStX - LILowPathNam - LIUpPathNam]
  fmul     f10p8
  fldcw      CW1
  fistp    dword ptr[esp - LCW - LStX - LIUpPathNam]
  fld      tbyte ptr[esp - LCW - LStX]
  fldcw     word ptr[esp - LCW]
  movq     xmm0, qword ptr[esp - LCW - LStX - LIUpPathNam - LILowPathNam]
  cvtdq2ps xmm0, xmm0
  movaps   xmm1, xmm0
  mulps    xmm0, xmmword ptr f10m4
  roundps  xmm0, xmm0, ROUND_TOWARD_ZERO
  movaps   xmm2, xmm0
  mulps    xmm2, xmmword ptr f10p4
  subps    xmm1, xmm2
  unpcklps xmm0, xmm1
  movaps   xmm1, xmm0
  mulps    xmm0, xmmword ptr f10m2
  roundps  xmm0, xmm0, ROUND_TOWARD_ZERO
  movaps   xmm2, xmm0
  mulps    xmm2, xmmword ptr f10p2
  subps    xmm1, xmm2
  movaps   xmm2, xmm1
  mulps    xmm1, xmmword ptr f10m1
  roundps  xmm1, xmm1, ROUND_TOWARD_ZERO
  movaps   xmm3, xmm1
  mulps    xmm3, xmmword ptr f10p1
  subps    xmm2, xmm3
  cvtps2dq xmm1, xmm1
  cvtps2dq xmm2, xmm2
  pslld    xmm2, 8
  paddb    xmm1, xmm2
  movaps   xmm2, xmm0
  mulps    xmm0, xmmword ptr f10m1
  roundps  xmm0, xmm0, ROUND_TOWARD_ZERO
  movaps   xmm3, xmm0
  mulps    xmm3, xmmword ptr f10p1
  subps    xmm2, xmm3
  cvtps2dq xmm0, xmm0
  cvtps2dq xmm2, xmm2
  pslld    xmm2, 8
  paddb    xmm0, xmm2
  pslld    xmm1, 16
  paddb    xmm0, xmm1
  pxor     xmm3, xmm3
  pcmpeqb  xmm3, xmm0
  pmovmskb  eax, xmm3
  bts       eax, 10h
  bsr       eax, eax
  paddb    xmm0, xmmWord ptr i30h
  movdqu   [esp - LString + byte], xmm0
  mov      qword ptr[esp - LString + byte + eax], rdx
  movd     xmm0, rdx
  pxor     xmm1, xmm1
  pcmpeqb  xmm1, xmm0
  pmovmskb  edx, xmm1
  bsf       edx, edx
  lea       eax,[eax + edx + word + byte]
  mov     dl,[esp - LString + byte]
  mov     dh,'.'
  mov        [esp - LString], dx
  mov     ecx,   dword ptr[esp - LString - dword - byte]
  sub     eax, ecx
  movdqu xmm1, xmmword ptr[esp - LString +   ecx - byte]
  movdqu xmm2, xmmword ptr[esp - LString +   ecx - byte + xmmword]
  mov     ecx, eax
WinMain endp
end
Зачем писать этот код если ранее ты уже разместил код про который заявил что он самый быстрый - потому что этот код еще быстрей.Чем он лучше предыдущего - в этом коде векторизовано разложение Числа на числа.Почему в нем одновременно используются FPU и SIMD - потому что в FPU есть режим расширенной точности позволяющий извлечь 16 значащих цифр.
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_programmirovanie (Программирование), #_assembler, #_programmirovanie (программирование), #_assembler, #_programmirovanie (
Программирование
)
, #_assembler
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 22-Ноя 10:02
Часовой пояс: UTC + 5