1. Почему использован 32-битный код, а не 64-битный?
2. Зачем столько пушей в _pifagor_hpi?
3. Зачем finit в _pifagor_fpu?
4. Зачем enter, leave и адресация по ebp, если можно сразу по esp? Кстати, в _pifagor_fpu вместо enter использован эквивалент: push ebp / mov ebp, esp. А почему тогда в _pifagor_hpi использован еще один подход.
5. В _pifagor_fpu обращение к стеку по незарезервированному месту ([ebp - 4]). Переключение задачи между fist и последующим mov перезатрет значение.
По моему, подчистив можно серьезно ускорить. И нужен другой метод измерения: time не учитывает переключение задач.
1. У меня в практике ещё много 32-х битных аппаратов. И опыта с 64 битами мало, возможно, стоит попробовать реализовать, но после разбора с 32 битами.
2. Перестраховался: мало ли компилятор С перед вызовом процедуры что-то будет держать в регистрах? Он обязан сделать что-то, вроде,
pushad или нет? Кстати, сопутствующее, если изменить передачу параметров на __fastcall, то можно ли будет уйти от стека вообще?
3. Без finit вычисления были очень замедлены, и через 10 вычислений начиналась ошибка. Первым делом решил переинициализировать - помогло, но причина самому интересна.
4. Не знал, как события развернутся. Сначала думал регистров не хватит, придётся использовать стек, а потом оказалось всё в порядке, хотя была бы третья или четвёртая степень, например, для сплайна, тут уже не развернёшься.
enter я подзабыл, можно записать
enter 4, 0, если правильно помню первый параметр, как раз аренда под локальные переменные. В hpi ebp играет роль сначала указателя, а потом переменной.
leave сначала поместит в esp ebp, что недопустимо. Поэтому в конце программы сначала извлекается истинный ebp, затем сдвигаю esp, чтобы удалить то, что было в пушах.
5. Сорри.
Какой метод измерения лучше?
Добавлено через 32 минуты и 19 секунд:__fastcall в tcc работает, но с особенностями.
_pifagor_fpu
_pifagor_fpu:
; Функция: __fastcall
; ecx - параметр х
; edx - параметр у
push ecx
push edx
finit
fild dword [esp + 4]
fmul st0, st0
fild dword [esp]
fmul st0, st0
fadd st0, st1
fsqrt
fist dword [esp + 4]
pop eax
pop eax
ret
Удаление
finit, также приводит к ошибкам.