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

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

Пароль



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

Забыли пароль?
Запросите новый здесь.
Темы форума
Достигните новых выс…
Сегодня, 16:04
 sonnick84
WoL
Вчера, 09:43
 VoroneTZ
Как с минимальными з…
29.04.2024
 sonnick84
185 - RPG
9.02.2024
 Vaskrol
В каком банке открыт…
24.01.2024
 Darthman
185 - ?
30.12.2023
 Mefistofel
TESTAMENT - Тактичес…
15.11.2023
 KregHek
RES - Движок для пик…
27.09.2023
 rimush
177 - One Button Str…
20.09.2023
 VoroneTZ
JS 13k contest
13.09.2023
 Mefistofel
Сейчас на сайте
Гостей: 4
На сайте нет зарегистрированных пользователей

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

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

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

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

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

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

Function NormalizeSize(int : integer) : integer;
asm
bsr ecx, eax
mov edx, 2
add eax, eax
shl edx, cl
cmp eax, edx
jne @ne
shr edx, 1
@ne :
mov eax, edx
end;


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

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

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

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

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

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

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

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

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

Опубликовано 20.11.2006 16:19 (17 лет назад)    #
function NextPowerOfTwo(Value: Integer): Integer;
begin
Result:= 1;
asm
xor ecx, ecx
bsr ecx, Value
inc ecx
shl Result, cl
end;
end;

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

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

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

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

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

Опубликовано 20.11.2006 16:50 (17 лет назад)    #
function NextPowerOfTwo(Value: Integer): Integer;
begin
Result:= 1;
asm
xor ecx, ecx
bsr ecx, Value
inc ecx
shl Result, cl
end;
end;

//---------------------------------------------------------------------------

function IsPowerOfTwo(Value: Integer): Boolean;
begin
Result:= (Value >= 1) and ((Value and (Value - 1)) = 0);
end;

//---------------------------------------------------------------------------

function CeilPowerOfTwo(Value: Integer): Integer; register;
asm
xor eax, eax
dec ecx
bsr ecx, ecx
cmovz ecx, eax
setnz al
inc eax
shl eax, cl
end;

//---------------------------------------------------------------------------

function FloorPowerOfTwo(Value: Integer): Integer;
asm
xor eax, eax
bsr ecx, ecx
setnz al
shl eax, cl
end;

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

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

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

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

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

Опубликовано 28.11.2006 15:56 (17 лет назад)    #
Из стандартных финкций(может кто не знает):
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 (17 лет назад)    #
CHASER дает разрядность числа в двоичной системе.
Spirit
Avatar пользователя

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


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

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

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

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

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

const
_p180 : extended = 3.14159265358979323846264 / 180;
_180p : extended = 180 / 3.14159265358979323846264;

function Pi : extended; inline(
$D9/$EB { fldpi }
);

function E : extended; inline(
$D9/$E8/ { fld1 }
$D9/$EA/ { fldl2e }
$D8/$E1/ { fsub st,st(1) }
$D9/$F0/ { f2xm1 }
$D9/$C9/ { fxch }
$DC/$C1/ { fadd st(1),st }
$D8/$C0/ { fadd st,st }
$DE/$C9 { fmulp }
);

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

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

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

function GArcTan(a : double) : double; inline(
$8B/$DC/ { mov bx,sp }
$36/$DD/$07/ { fld qword ptr ss:[bx] }
$D9/$E8/ { fld1 }
$83/$C4/$08/ { add sp,8 }
$D9/$F3/ { fpatan }
$DB/$2E/_180p/ { fld tbyte ptr [_180p] }
$DC/$C9/ { fmul qword ptr ss:[bx] }
$DD/$C0/
$D9/$F7
);

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

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

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

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

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

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

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

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

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

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

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

Опубликовано 10.09.2008 06:09 (16 лет назад)    #
да спирит прав, для паскаля сия библиотека была написана, в дельфи надо просто инлайны отрубить
на счет скорости выигрыш есть раза в 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 (16 лет назад)    #
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

Перейти на форум:
Конкурсы
Открытые конкурсы:
Активных нет
Недавние конкурсы:
 185 - RPG XII
 184 - Arcade II
 183 - Novel
 182 - RPG XI
 181 - Pixel Craft 128
 Все конкурсы
Случайная игра
Мини-чат
Вам необходимо залогиниться.

Архив чата

25,408,858 уникальных посетителей

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