1. Если вы только начинаете программировать на ассемблере и не знаете с чего начать, тогда попробуйте среду разработки ASM Visual IDE
    (c) на правах рекламы
    Скрыть объявление

Портирование FPU на SSE

Тема в разделе "WASM.ASSEMBLER", создана пользователем Mikl___, 14 июл 2020.

  1. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    2.987
    M0rg0t,
    не секрет, для OpenGL. Там практически все расчеты в вещественных числах и передача параметров через XMM0-XMM3. И да, быстрее :yes3: OpenGL in masm64
     
    M0rg0t и UbIvItS нравится это.
  2. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    630
    Всё к этому и идёт. В VisualStudio уже нельзя сгенерить код для long double 80 bit (только на асме).
     
  3. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    5.269
    не, его ещё долго не выкинут..
    а на таком https://dalthron.com.pe/product/laptop-hp-245-g7-amd-ryzen-3-1tb-8gb-ram-freedos/ ещё и фридос запускается :)
     
  4. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    3.900
    UbIvItS,

    sse/mmx блоки ведь не для расчёта тригонометрии. А если выкинуть fpu, то это изменение всей архитектуры - как обрабатывать ошибки, ловушки и прочие вещи(нп осевой планировщик не тупо крутит мат блоки, он их оптимизирует выключая мат блоки на новых квантах). Если отказаться от fpu, то это будет уже не IA. Что все утверждают что новые мат блоки быстрее это всё фигня, где реальные цифры, как всегда где замеры по профайлу ?

    Кто там выше утверждал что реализовал Тейлор на sse, где примеры тесты профайл ?
     
  5. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    5.269
    Indy_,
    aida64
    prime95
    https://www.codeproject.com/Articles/21024/Inner-Product-Experiment-CPU-FPU-vs-SSE
    тестЬ сколько хОшЪЪЪ. другой Вопрос, что фпу и векторные регистры всё же несколько разные вещи == фпу -- это скалярные вычисления и аж 80бит число, а векторные регистры позволяют проводить пакетные операции, но точность страдает. т.е. лобовое сравнение тут не очень уместно.
     
  6. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    3.900
    UbIvItS,

    Тут задача в реализации тригонометрии через блоки расширения(sse etc). Тоесть софт реализация вычислений, Тейлор/Маклорен/etc. Конечный результат не обязательно в регистрах хранить, всё равно они выгружаются в память при чтении. По ссылке никакой тригонометрии не обнаружил.
     
  7. Jin X

    Jin X Active Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    359
    Адрес:
    Кольца Сатурна
    Indy_, Delphi 10.4 (последний): x86 использует FPU, x64 – SSE2.
    Тестим:
    Код (Text):
    1. {$APPTYPE CONSOLE}
    2. uses Winapi.Windows;
    3. var
    4.   C, i: Integer;
    5.   D, delta: Double;
    6.  
    7. begin
    8.   D := 0;
    9.   delta := Pi / 18000000;
    10.   C := GetTickCount;
    11.   for i := 1 to 36000000 do
    12.   begin
    13.     D := D + delta;
    14.     Sin(D);
    15.   end;
    16.   C := GetTickCount - C;
    17.   WriteLn(C);
    18. end.
    x86 ≈ 1350
    x64 ≈ 875

    Заменяем Sin на Exp: 1150 / 750.
    Ln у обоих 780.
     
    Последнее редактирование: 29 июл 2020
  8. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    3.900
    Jin X,

    Теорию относительности читал, константа не имеет смысла если её не с чем сравнить. Получилось значение для fpu-sin. Теперь нужен тот же цикл для реализации син через Тейлор-sse.

    А в общем нужно глянуть на саму дельфовую sin() дизом, не известно что там, я дельфи никогда не юзал. Для математики лучший сборщик басик как не удивительно https://www.purebasic.com/

    Дельфи тут глупо приводить в пример, это дичь.
     
  9. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    5.269
    тут имеем место быть несколько иная хистория...
    https://randomascii.wordpress.com/2014/10/09/intel-underestimates-error-bounds-by-1-3-quintillion/
    http://notabs.org/fpuaccuracy/
     
  10. Jin X

    Jin X Active Member

    Публикаций:
    0
    Регистрация:
    15 янв 2009
    Сообщения:
    359
    Адрес:
    Кольца Сатурна
    Так, я ж говорю, что x86 – это fpu, а x64 – sse2 (Тейлор).
    Там не нужен дизасм, там есть исходники этих функций. Я их смотрел (да и под дизасмом тоже), там именно то, что я написал.

    Не вопрос:
    Код (ASM):
    1. format  PE64 Console 5.0
    2. include 'win64axp.inc'
    3.  
    4. ;-- CODE SECTION -------------------------------------------------------------------------------------------------------
    5.  
    6. .code
    7.  
    8. entry:
    9.  
    10. frame
    11.                 finit
    12.                 fldz
    13.  
    14.                 invoke  GetTickCount
    15.                 mov     ebx,eax
    16.  
    17.                 mov     ecx,36000000
    18.         @@:
    19.                 fadd    [delta]
    20.                 fld     st
    21.                 fsin
    22.                 fstp    st
    23.                 dec     ecx
    24.                 jnz     @B
    25.  
    26.                 fstp    st
    27.  
    28.                 invoke  GetTickCount
    29.                 sub     eax,ebx
    30.  
    31.                 cinvoke printf, <'%d',10>, eax
    32.                 invoke  ExitProcess, 0
    33. endf
    34.  
    35. ;-- DATA SECTION -------------------------------------------------------------------------------------------------------
    36.  
    37. .data
    38.  
    39. delta           dq      1.745329251994e-7
    40.  
    41. ;-- IMPORT SECTION -----------------------------------------------------------------------------------------------------
    42.  
    43. section '.idata' import data readable
    44.  
    45. library kernel32, 'kernel32.dll',\
    46.         msvcrt, 'msvcrt.dll'
    47.  
    48.         import_kernel32
    49.         all_api
    50.  
    51. import  msvcrt,\
    52.         printf, 'printf'
    У меня выдаёт ≈ 1150.
    Если уж "дичь"-sse2/Тейлор работает на 30+% быстрее, чем чистый асм-fpu, то что уж говорить о "нормальной" реализации Тейлора? :)
    --- Сообщение объединено, 30 июл 2020 ---
    А вообще говоря, улучшить её можно как минимум бóльшим "распараллеливанием" вычислений, чем в Delphi.
    Надо ещё на плюсах попробовать. По любому там будет sse2 под x64 (по крайней мере, под какие-то компиляторы).
     
    Последнее редактирование: 30 июл 2020
  11. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    5.269
    ряды и полиномы на большой точности медлительны + имеется нарастающая проблема округления == лучше кордик использовать.
     
    Jin X нравится это.
  12. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    3.900
    Jin X,

    > x86 – это fpu, а x64 – sse2

    И что межу ними общего. Это не замер, а чушь. Сравнение профайла на разных архитектурах. А есчо покажи где тригон вычисляется через sse, дельфя такое врядле умеет.

    > Я их смотрел

    В студию сурки или диз. Что ты видел никого не волнует, может у тебя глюки кто знает :)
     
  13. maalchemist

    maalchemist New Member

    Публикаций:
    0
    Регистрация:
    1 дек 2016
    Сообщения:
    6
    В Delphi (x64) синус выглядит так:

    [​IMG]
     
    Indy_ нравится это.
  14. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    3.900
    maalchemist,

    Какой то полином, начало ряда:

    r6 = ([487] * (r0^2)^2 + [47f]) * (r0^2)^2 + [477]
    r4 = ((([487] * (r0^2)^2 + [483]) * ((r0^2)^2 + [47b]*2) * r0^2 + r6 + [46B]) * r0^2

    Врядле может быть какая то точность. Но уже больше похоже на правду. Это нужно сравнить по таймингу с fsin.
     
    Последнее редактирование: 1 авг 2020
  15. maalchemist

    maalchemist New Member

    Публикаций:
    0
    Регистрация:
    1 дек 2016
    Сообщения:
    6
    Дельфийский SSE-синус возвращает абсолютно такой же результат, что и FPU:fsin, если аргумент <= 18003.
    Для косинуса результаты совпадают, если аргумент <= 17908.
    Только что проверил.
     
  16. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    3.900
    maalchemist,

    Тогда получается что хард fsin использует тот же полином.

    А что по таймингу ?
     
  17. maalchemist

    maalchemist New Member

    Публикаций:
    0
    Регистрация:
    1 дек 2016
    Сообщения:
    6
    Однако для разных аргументов получаются существенно разные времена.
    Если сравнивать встроенный SSE-синус вот с такой функцией,
    Код (Text):
    1. function FPU_fsin (a: Double): Double;
    2. asm
    3.   sub     rsp, 16
    4.   movupd  dqword ptr [rsp], xmm0
    5.   fld     qword ptr [rsp]
    6.   fsin
    7.   fstp    qword ptr [rsp]
    8.   movupd  xmm0, dqword ptr [rsp]
    9.   add     rsp, 16
    10. end;
    11.  
    то для аргумента 0.01 SSE-версия работает в 4.4 раза быстрее.

    Для других аргументов имеем такие результаты:
    0.1 - 4.4
    1.0 - 2.8
    5.0 - 1.5
    10.0 - 1.3
    100.0 - 1.3
    1000.0 - 1.5
    10000.0 - 1.5
    100000.0 - 1.04
    1000000.0 - 1.3
     
    Indy_ нравится это.
  18. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    3.900
    maalchemist,

    А длительность замера какая, это важно тк это теже блоки fpu и планировщик их выгружает.
     
  19. maalchemist

    maalchemist New Member

    Публикаций:
    0
    Регистрация:
    1 дек 2016
    Сообщения:
    6
    Для оценки я использовал вот такую простенькую функцию:
    Код (Text):
    1. function FPU_SSE_sin_TEST (a: Double): Double;
    2. var
    3.   I      : Integer;
    4.   I1, I2 : Int64;
    5.   J1, J2 : Int64;
    6.   ID, JD : Double;
    7.   Ratio  : Double;
    8. begin
    9.   QueryPerformanceCounter (I1);
    10.   for I := 1 to 1000000 do begin
    11.     FPU_fsin (a);
    12.   end;
    13.   QueryPerformanceCounter (I2);
    14.   ID := I2 - I1;
    15.  
    16.   QueryPerformanceCounter (J1);
    17.   for I := 1 to 1000000 do begin
    18.     sin (a);
    19.   end;
    20.   QueryPerformanceCounter (J2);
    21.   JD := J2 - J1;
    22.  
    23.   Ratio := ID / JD;
    24.   Result := Ratio;
    25. end;
    26.  
     
  20. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    3.900
    maalchemist,

    Если длительность менее кванта профайл будет невалид. Нужно либо очень большое значение dTSC, либо лучше использовать GetTickCount().