![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
|
|
#1
|
|||
|
|||
|
Всем привет!
Пишу графику и мне в расчётах нужно отбрасывать дробную часть переводя в целое. Так вот Trunc работает в два раза дольше чем Round. Время для меня очень критично, поэтому ищу варианты решения данной задачи. Ассемблерные вставки не помогают или я делаю что то не так... У кого есть какие идеи? Вот код: Код:
dx := w1 / w2;
dy := h1 / h2;
for y := 0 to h2 - 1 do
begin
yp := Trunc(y * dy);
ypw1 := yp * w1;
yw2 := y * w2;
for x := 0 to w2 - 1 do
begin
xp := Trunc(x * dx);
col := ypw1 + xp;
Mem2[yw2 + x] := Mem1[col];
end;
end; |
|
#2
|
||||
|
||||
|
Не быстрее Round, но быстрее Trunc.
Код:
function Trunc_Dbl(Value: Double): Integer;
var
d_w: array[0..3] of word absolute Value;
begin
Result := ((d_w[3] shl 11) or (d_w[2] shr 5) or $8000) shr (14 - (d_w[3] shr 4 and $03FF));
end;
function Trunc_Asm(Value: Double): Integer;
const
Half: double = 0.5;
begin
asm
fld Value
fsub Half
fistp Result
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
tc1, tc2, tc3, tc4: Cardinal;
_value: Double;
_result: Integer;
begin
_value := 100.56;
tc1 := GetTickCount;
for I := 0 to $FFFFFF do
begin
_result := Trunc(_value);
if _result = 99 then
;
end;
tc1 := GetTickCount - tc1;
//-------------
tc2 := GetTickCount;
for I := 0 to $FFFFFF do
begin
_result := Trunc_Asm(_value);
if _result = 99 then
;
end;
tc2 := GetTickCount - tc2;
//-------------
tc3 := GetTickCount;
for I := 0 to $FFFFFF do
begin
_result := Trunc_Dbl(_value);
if _result = 99 then
;
end;
tc3 := GetTickCount - tc3;
//-------------
tc4 := GetTickCount;
for I := 0 to $FFFFFF do
begin
_result := Round(_value);
if _result = 99 then
;
end;
tc4 := GetTickCount - tc4;
//-------------
ShowMessageFmt('Trunc: %d'#13'Trunc_Asm: %d'#13'Trunc_Dbl: %d'#13'Round: %d', [tc1, tc2, tc3, tc4]);
end;![]() Последний раз редактировалось dr. F.I.N., 19.03.2018 в 19:20. |
|
#3
|
||||
|
||||
|
Покопавшись, нашел еще вариант. Полагаю то, что Вам нужно.
Код:
function TruncMEM_SSE(Var Value: Double): Integer; asm // as written, fatest version CVTTSD2SI EAX, [Value] end; ![]() И вот еще наблюдение. Код:
function Trunc_Dbl(var Value: Double): Integer; // VAR var d_w: array[0..3] of word absolute Value; begin Result := ((d_w[3] shl 11) or (d_w[2] shr 5) or $8000) shr (14 - (d_w[3] shr 4 and $03FF)); end; Последний раз редактировалось dr. F.I.N., 20.03.2018 в 11:30. |
|
#4
|
|||
|
|||
|
dr. F.I.N., спасибо, "TruncMEM_SSE" то что доктор прописал!
Ещё раз спасибо, тема закрыта |