Навигация
Поддержать материально
Steam Greenlight

Логотипы
Медальки
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Темы форума
WoL
14.03.2025
 Mefistofel
188 - RPG
17.02.2025
 Mefistofel
Привет выжившие
30.01.2025
 Darthman
Galactic Showdown -…
30.01.2025
 Darthman
188 - ?
1.01.2025
 Mefistofel
187 - Bullet Heaven
17.12.2024
 VoroneTZ
187 - ?
21.11.2024
 Dan
Новый IGDC
5.08.2024
 rimush
186 - Strategy!
15.07.2024
 VoroneTZ
185 - RPG
9.02.2024
 Vaskrol
Сейчас на сайте
Гостей: 1
На сайте нет зарегистрированных пользователей

Пользователей: 1,792
новичок: IAmNotARobot
Обсуждение «Быстрые процедуры...»
DeadMeat
Avatar пользователя

Опубликовано 19.05.2006 14:04 (19 лет назад)    #
Помню вроде бы на ДМе была веточка. Или где то еще.
Короче смысл таков. Выкладывайте сюда то, что есть у вас.
Не большие шустрые полезные процедурки.
Любые, которые могут пригодиться. Оптимизированные.
Если не жалко конечно.

Вот к примеру есть функция вычисления синуса/косинуса. В System.pas.
У кого нить есть аналог, но чтобы пошустрее?
Я не говорю, что те медленные, но просто.. чисто из интереса. У меня не получилось сделать. Если это не реально - другое дело. Я просто точно не знаю.
Ну это так.. для затравки.

редакция от DeadMeat, 19.05.2006 14:05

Darthman
Древний организм
Avatar пользователя

Опубликовано 19.05.2006 14:14 (19 лет назад)    #
Помнится я выкладывал чертовски шуструю процедуру, для вычисления ближайшего БОЛЬШЕГО (либо равного) n-битного числа (2, 4, 8, 16, 32... и т.д.) к указанному.
пример: 33 = 64; 256 = 256; 500 = 512 и так далее.

  1. Function NormalizeSize(int : integer) : integer;
  2. asm
  3. bsr ecx, eax
  4. mov edx, 2
  5. add eax, eax
  6. shl edx, cl
  7. cmp eax, edx
  8. jne @ne
  9. shr edx, 1
  10. @ne :
  11. mov eax, edx
  12. end;


Выполняется за оч. маленькое кол-во тактов, ибо оптимизирована по самое нехочу :) Применение различно. Например если есть текстура како-то разрешения, а для правильности надо ее догнать до степени двойки, то этой процедурой легко вычислить правильную размерность для новой текстуры. Другие применения думаю и сами найдете без лишних проблем. Оптимизировал чисто для интереса, так как надобности в скоростией этой процедуры не было. Размер передаваемого значения не влияет на скорость выполнения.

редакция от Darthman, 19.05.2006 14:25

XProger
Avatar пользователя

Опубликовано 19.05.2006 16:22 (19 лет назад)    #
DeadMeat, с каких пор ты об оптимизации стал думать? Кто тебя так обидел? ;)
  1. procedure SinCos(const Theta: Extended; var Sin, Cos: Extended);
  2. asm
  3. FLD Theta
  4. FSINCOS
  5. FSTP tbyte ptr [edx] // Cos
  6. FSTP tbyte ptr [eax] // Sin
  7. FWAIT
  8. end;
DeadMeat
Avatar пользователя

Опубликовано 21.05.2006 11:56 (19 лет назад)    #
XProger,
Я просил чтото свое, а не содержимое стандартных модулей....

редакция от DeadMeat, 21.05.2006 11:57

Anton Andreevitch
Avatar пользователя

Опубликовано 21.05.2006 16:14 (19 лет назад)    #
а вдруг в стандартных модулях - его? :)
DeadMeat
Avatar пользователя

Опубликовано 29.05.2006 11:57 (19 лет назад)    #
Мда... Просмотров дофига, а постов всего 4.
Жаль..
CHASER
Avatar пользователя

Опубликовано 20.11.2006 16:19 (18 лет назад)    #
  1. function NextPowerOfTwo(Value: Integer): Integer;
  2. begin
  3. Result:= 1;
  4. asm
  5. xor ecx, ecx
  6. bsr ecx, Value
  7. inc ecx
  8. shl Result, cl
  9. end;
  10. end;

Во, работать не быстрее будет? (Я не знаю, она не моя)

Кстати для синусов и косинусов можно юзать хеш-таблицы...

редакция от CHASER, 20.11.2006 16:21

Darthman
Древний организм
Avatar пользователя

Опубликовано 20.11.2006 16:40 (18 лет назад)    #
Нет, ибо оно дает следующее число степени двойки. представленная мной процедура приводит ближайшее большее число равное степени двойки. Тоесть работает с любыми числами.
А по вопросу - да быстрее работает :) но не так.
CHASER
Avatar пользователя

Опубликовано 20.11.2006 16:50 (18 лет назад)    #
  1. function NextPowerOfTwo(Value: Integer): Integer;
  2. begin
  3. Result:= 1;
  4. asm
  5. xor ecx, ecx
  6. bsr ecx, Value
  7. inc ecx
  8. shl Result, cl
  9. end;
  10. end;

  11. //---------------------------------------------------------------------------

  12. function IsPowerOfTwo(Value: Integer): Boolean;
  13. begin
  14. Result:= (Value >= 1) and ((Value and (Value - 1)) = 0);
  15. end;

  16. //---------------------------------------------------------------------------

  17. function CeilPowerOfTwo(Value: Integer): Integer; register;
  18. asm
  19. xor eax, eax
  20. dec ecx
  21. bsr ecx, ecx
  22. cmovz ecx, eax
  23. setnz al
  24. inc eax
  25. shl eax, cl
  26. end;

  27. //---------------------------------------------------------------------------

  28. function FloorPowerOfTwo(Value: Integer): Integer;
  29. asm
  30. xor eax, eax
  31. bsr ecx, ecx
  32. setnz al
  33. shl eax, cl
  34. end;

Вот, все что есть. (ЗЫ. Это из исходников Asphyre)

редакция от CHASER, 20.11.2006 16:51

Darthman
Древний организм
Avatar пользователя

Опубликовано 20.11.2006 18:11 (18 лет назад)    #
Понятно. Лайфповер маньяк :)
CHASER
Avatar пользователя

Опубликовано 20.11.2006 19:11 (18 лет назад)    #
Кстати, можешь обьяснить, то делает bsr?
2morrowMan
Avatar пользователя

Опубликовано 28.11.2006 15:56 (18 лет назад)    #
Из стандартных финкций(может кто не знает):
function Hypot(const X, Y: Extended): Extended; - длина гипотенузы правильного треугольника или же длина вектора.
Это вместо: Sqrt(Sqr(x) + Sqr(y));

редакция от 2morrowMan, 28.11.2006 15:57

Darthman
Древний организм
Avatar пользователя

Опубликовано 28.11.2006 16:20 (18 лет назад)    #
CHASER дает разрядность числа в двоичной системе.
Spirit
Avatar пользователя

Опубликовано 09.09.2008 11:21 (17 лет назад)    #
DeadMeat написал:
Вот к примеру есть функция вычисления синуса/косинуса. В System.pas.
У кого нить есть аналог, но чтобы пошустрее?
Ну это так.. для затравки.


CHASER правильно сказал. Самое оптимальное - ХЭШ-таблицы, но потеря точности. Чем больше ХЭШ-таблица, тем выше точность, но появляется overhead на сбоях кэша. Второй вариант ускорения синуса и косинуса - разложить в ряд. Чем больше членов ряда используешь в сумме, тем точнее результат. Но, имхо, в таком случае получить приемлемую точность за более короткое время (чем уже есть в system.pas) имхо нереально (надо погонять, потестировать)...

Сорри за некрофильство, не мог пройти мимо ;)

редакция от Spirit, 09.09.2008 11:26

Gambit_oz
Avatar пользователя

Опубликовано 09.09.2008 12:45 (17 лет назад)    #
Дай ка тоже вфигачу свои пять копеек))

  1. const
  2. _p180 : extended = 3.14159265358979323846264 / 180;
  3. _180p : extended = 180 / 3.14159265358979323846264;

  4. function Pi : extended; inline(
  5. $D9/$EB { fldpi }
  6. );

  7. function E : extended; inline(
  8. $D9/$E8/ { fld1 }
  9. $D9/$EA/ { fldl2e }
  10. $D8/$E1/ { fsub st,st(1) }
  11. $D9/$F0/ { f2xm1 }
  12. $D9/$C9/ { fxch }
  13. $DC/$C1/ { fadd st(1),st }
  14. $D8/$C0/ { fadd st,st }
  15. $DE/$C9 { fmulp }
  16. );

  17. function Tan(a : double) : double; inline(
  18. $8B/$DC/ { mov bx,sp }
  19. $36/$DD/$07/ { fld qword ptr ss:[bx] }
  20. $D9/$F2/ { fptan }
  21. $83/$C4/$08/ { add sp,8 }
  22. $DD/$D8 { fstp st }
  23. );

  24. { àíàëîãè÷íî òàíãåíñó Tan(a), íî âåëè÷èíà â ãðàäóñàõ }
  25. function GTan(a : double) : double; inline(
  26. $8B/$DC/ { mov bx,sp }
  27. $DB/$2E/_p180/ { fld tbyte ptr [_p180] }
  28. $36/$DC/$0F/ { fmul qword ptr ss:[bx] }
  29. $D9/$F2/ { fptan }
  30. $83/$C4/$08/ { add sp,8 }
  31. $DD/$D8 { fstp st }
  32. );

  33. function ArcTan(a : double) : double; inline(
  34. $8B/$DC/ { mov bx,sp }
  35. $36/$DD/$07/ { fld qword ptr ss:[bx] }
  36. $D9/$E8/ { fld1 }
  37. $83/$C4/$08/ { add sp,8 }
  38. $D9/$F3 { fpatan }
  39. );

  40. function GArcTan(a : double) : double; inline(
  41. $8B/$DC/ { mov bx,sp }
  42. $36/$DD/$07/ { fld qword ptr ss:[bx] }
  43. $D9/$E8/ { fld1 }
  44. $83/$C4/$08/ { add sp,8 }
  45. $D9/$F3/ { fpatan }
  46. $DB/$2E/_180p/ { fld tbyte ptr [_180p] }
  47. $DC/$C9/ { fmul qword ptr ss:[bx] }
  48. $DD/$C0/
  49. $D9/$F7
  50. );

  51. function Sin(a : double) : double; inline(
  52. $8B/$DC/ { mov bx,sp }
  53. $36/$DD/$07/ { fld qword ptr ss:[bx] }
  54. $D9/$FE/ { fsin }
  55. $83/$C4/$08 { add sp,8 }
  56. );

  57. function GSin(a : double) : double; inline(
  58. $8B/$DC/ { mov bx,sp }
  59. $DB/$2E/_p180/ { fld tbyte ptr [_p180] }
  60. $36/$DC/$0F/ { fmul qword ptr ss:[bx] }
  61. $D9/$FE/ { fsin }
  62. $83/$C4/$08 { add sp,8 }
  63. );

  64. function Cos(a : double) : double; inline(
  65. $8B/$DC/ { mov bx,sp }
  66. $36/$DD/$07/ { fld qword ptr ss:[bx] }
  67. $D9/$FF/ { fcos }
  68. $83/$C4/$08 { add sp,8 }
  69. );

  70. function GCos(a : double) : double; inline(
  71. $8B/$DC/ { mov bx,sp }
  72. $DB/$2E/_p180/ { fld tbyte ptr [_p180] }
  73. $36/$DC/$0F/ { fmul qword ptr ss:[bx] }
  74. $D9/$FF/ { fcos }
  75. $83/$C4/$08 { add sp,8 }
  76. );

  77. function Ln(a : double) : double; inline(
  78. $8B/$DC/ { mov bx,sp }
  79. $D9/$ED/ { fldln2 }
  80. $36/$DD/$07/ { fld qword ptr ss:[bx] }
  81. $D9/$F1/ { fyl2x }
  82. $83/$C4/$08 { add sp,8 }
  83. );

  84. function Log(a : double) : double; inline(
  85. $8B/$DC/ { mov bx,sp }
  86. $D9/$EC/ { fldlg2 }
  87. $36/$DD/$07/ { fld qword ptr ss:[bx] }
  88. $D9/$F1/ { fyl2x }
  89. $83/$C4/$08 { add sp,8 }
  90. );

  91. { ëîãàðèôì ÷èñëà Y ïî îñíîâàíèþ X }
  92. function LogX(y,x : double) : double; inline(
  93. $8B/$DC/ { mov bx,sp }
  94. $D9/$E8/ { fld1 }
  95. $D9/$E8/ { fld1 }
  96. $36/$DD/$47/$08/ { fld qword ptr ss:[bx+8] }
  97. $D9/$F1/ { fyl2x }
  98. $DE/$F9/ { fdivp }
  99. $36/$DD/$07/ { fld qword ptr ss:[bx] }
  100. $D9/$F1/ { fyl2x }
  101. $83/$C4/$10 { add sp,16 }
  102. );

  103. { Ðàáîòàåò êîððåêòíî äî X <= 0.8 }
  104. function SmallExp(x : double) : double; inline(
  105. $8B/$DC/ { mov bx,sp }
  106. $D9/$E8/ { fld1 }
  107. $36/$DD/$07/ { fld qword ptr ss:[bx] }
  108. $D9/$EA/ { fldl2e }
  109. $83/$C4/$08/ { add sp,8 }
  110. $DE/$C9/ { fmulp }
  111. $D9/$F0/ { f2xm1 }
  112. $DE/$C1 { faddp }
  113. );

  114. { åñëè áèò BitNum óñòàíîâëåí, âîçâðàùàåò TRUE }
  115. function Bit(x : longint; BitNum : word) : wordbool; inline(
  116. $59/ { pop cx }
  117. $66/$5B/ { pop ebx }
  118. $66/$33/$C0/ { xor eax,eax }
  119. $FE/$C0/ { inc al }
  120. $66/$D3/$E0/ { shl eax,cl }
  121. $66/$23/$C3/ { and eax,ebx }
  122. $66/$D3/$E8 { shr eax,cl }
  123. );
Adler
Avatar пользователя

Опубликовано 09.09.2008 17:55 (17 лет назад)    #
Gambit_oz и каким макаром этот чудо код компилируется?
Spirit
Avatar пользователя

Опубликовано 09.09.2008 20:57 (17 лет назад)    #
Компилируется как инлайн код. По крайней мере в Turbo/Borland Pascal такое компилировалось. Не знаю, как в Delphi/BDS...
По быстродействию выигрыш совсем небольшой, только за счет исключения вызова подпрограмм (манипуляции со стековыми фреймами можно исключить и без инлайна).
Gambit_oz
Avatar пользователя

Опубликовано 10.09.2008 06:09 (17 лет назад)    #
да спирит прав, для паскаля сия библиотека была написана, в дельфи надо просто инлайны отрубить
на счет скорости выигрыш есть раза в 2
например

function Tan(a : double) : double;
asm
mov bx,sp
fld qword ptr ss:[bx]
fptan
add sp,8
fstp st
end;
Spirit
Avatar пользователя

Опубликовано 10.09.2008 16:30 (17 лет назад)    #
2 Gambit_oz:
выигрышь в два раза - не совсем корректно считаете. Для начала добавьте директиву assembler:

function Tan(a : double) : double; assembler;
asm
mov bx,sp
fld qword ptr ss:[bx]
fptan
add sp,8
fstp st
end;

Это исключит генерацию пролога и эпилога функции. Теперь разница по скорости должна быть немного меньше. Проверить можно по сгенерированному коду. И потом, большая зависимость от используемого процессора (размер кэша).

редакция от Spirit, 10.09.2008 16:35

Перейти на форум:
Конкурсы
Открытые конкурсы:
Активных нет
Недавние конкурсы:
 188 - RPG XIII
 187 - Bullet Heaven
 186 - Strategy
 185 - RPG XII
 184 - Arcade II
 Все конкурсы
Случайная игра
Мини-чат
Вам необходимо залогиниться.

Архив чата

27,159,051 уникальных посетителей

Создано на базе русской версии PHP-Fusion copyright © 2003-2006 by Nick Jones.
Released as free software under the terms of the GNU/GPL license.