процедура быстрее функции.. почему?

Любые обсуждения, не нарушающие правил форума.

Модератор: Модераторы

процедура быстрее функции.. почему?

Сообщение Sniper » 30.05.2006 23:20:00

Во время перевода libSIMD обнаружил, что процедура типа
Код: Выделить всё
procedure simd_vecs3_sub(a, b:TVector3f; var c:TVector3f);assembler;

быстрее
Код: Выделить всё
function simd_vecs3_sub(a, b: TVector3f):TVector3f;assembler;

Причём не просто быстрее а в 2 (два)! раза
Почему?
Sniper
постоялец
 
Сообщения: 472
Зарегистрирован: 28.05.2005 13:02:42

Сообщение STAKANOV » 30.05.2006 23:35:26

В 2 раза это если процедура маленькая. А так советую собрать оба варианта с опцией -a и сразу будет видна разница. Хотя подозреваю, что без оптимизации тут не обошлось (вроде должно быть наоборот).
Аватара пользователя
STAKANOV
энтузиаст
 
Сообщения: 1069
Зарегистрирован: 14.05.2006 21:26:24
Откуда: Зеленоград

Сообщение SovNarKom » 31.05.2006 00:22:32

В смысле??? Всю жизнь процедуры быстрее функций были,
под возвращаемое значение выделяется память
SovNarKom
постоялец
 
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]

Сообщение Sniper » 31.05.2006 16:33:12

Вот они родимые:
Код: Выделить всё
procedure simd_vecs3_sub(a, b:TVector3f; var c:TVector3f);assembler; register;
asm
       movq  mm0, [a]
       movq  mm2, [b]
       movd  mm1, [a+8]
       movd  mm3, [b+8]
       pfsub mm0, mm2
       pfsub mm1, mm3
       movq  [c], mm0
       movd  [c+8], mm1
       emms
end;

function simd_vecs3_sub_1(a, b: TVector3f):TVector3f;assembler; register;
asm
       movq  mm0, [a]
       movq  mm2, [b]
       movd  mm1, [a+8]
       movd  mm3, [b+8]
       pfsub mm0, mm2
       pfsub mm1, mm3
       movq  [Result], mm0
       movd  [Result+8], mm1
       emms
end;
Последний раз редактировалось Sniper 31.05.2006 16:38:42, всего редактировалось 6 раз(а).
Sniper
постоялец
 
Сообщения: 472
Зарегистрирован: 28.05.2005 13:02:42

Сообщение Иван Шихалев » 31.05.2006 16:36:11

Правильно. Память выделяется не внутри функции, а снаружи... Затем еще идет передача данных из Result в переменную, которой значение функции присваивается...
Аватара пользователя
Иван Шихалев
энтузиаст
 
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург

Сообщение Sniper » 31.05.2006 16:39:39

Вот вопрос в тему: Как вообще от этого Result отбиться?При чём begin/end использовать не получится...
Последний раз редактировалось Sniper 31.05.2006 16:41:08, всего редактировалось 1 раз.
Sniper
постоялец
 
Сообщения: 472
Зарегистрирован: 28.05.2005 13:02:42

Сообщение Иван Шихалев » 31.05.2006 16:41:06

В смысле "отбиться"? Возвращать только простые значения, которые влазят в регистры...
Аватара пользователя
Иван Шихалев
энтузиаст
 
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург

Сообщение Sniper » 31.05.2006 16:42:50

ну не могу же я написать
Код: Выделить всё
movq  [simd_vecs3_sub_1], mm0
movd  [simd_vecs3_sub_1+8], mm1

%)

А было бы хорошо )

В разные регисты Delphi и FPC рассовывают переменные?
Ответ: в одинаковые
Последний раз редактировалось Sniper 31.05.2006 17:07:28, всего редактировалось 1 раз.
Sniper
постоялец
 
Сообщения: 472
Зарегистрирован: 28.05.2005 13:02:42

Сообщение SovNarKom » 31.05.2006 16:57:59

Вот такой код работать должен
Код: Выделить всё
function geteipasebx : pointer; assembler;
asm
mov ebx, esp
ret
end;

Возвращает, как я понимаю в ebx...
SovNarKom
постоялец
 
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]

Сообщение Mirage » 02.06.2006 09:17:53

Sniper: По-моему ты такой вопрос уде задавал на этом форуме.:)
Функция возвращает такой результат как вектор через стек (целое обычно через EAX - зависит от calling convention). А процедура (с var параметром) изменяет непосредственно память. Тут есть подводный камень - если процедура должна изменять данные, а они еще должны быть ею использованы в оригинальном виде (например такое имеет место при перемножении матриц или матрицы на вектор), то получишь глюки. Причем глюки трудновычислимые, т.к. с виду-то все в порядке.:)
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Сообщение STAKANOV » 02.06.2006 10:57:39

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

Можно об этом подробней?
Аватара пользователя
STAKANOV
энтузиаст
 
Сообщения: 1069
Зарегистрирован: 14.05.2006 21:26:24
Откуда: Зеленоград

Сообщение Mirage » 02.06.2006 12:29:22

А чего собственно непонятного?
Допустим вектор множится на матрицу:
Код: Выделить всё
procedure Transform4Vector4s(var Result: TVector4s; const M: TMatrix4s; const V: TVector4s);
begin
  Result.X := M.M[0, 0] * V.X + M.M[1, 0] * V.Y + M.M[2, 0] * V.Z + M.M[3, 0] * V.W;
  Result.Y := M.M[0, 1] * V.X + M.M[1, 1] * V.Y + M.M[2, 1] * V.Z + M.M[3, 1] * V.W;
  Result.Z := M.M[0, 2] * V.X + M.M[1, 2] * V.Y + M.M[2, 2] * V.Z + M.M[3, 2] * V.W;
  Result.W := M.M[0, 3] * V.X + M.M[1, 3] * V.Y + M.M[2, 3] * V.Z + M.M[3, 3] * V.W;
end;
...
Transform4Vector4s(V, M, V);


Получится, что Result и V - одно и тоже. И после первой строчки V.X, используемый далее, будет уже иметь другое значение. Получаем неправильный результат. В случае функции такого не будет.
А вот если бы она не уступала по скорости процедуре, т.е. догадывалась бы отображать Result на переменную, то были бы такие же глюки. Так что правильно делают, что через стек.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Сообщение SovNarKom » 04.06.2006 14:20:41

Получится, что Result и V - одно и тоже.

Почему?! :shock:
SovNarKom
постоялец
 
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]

Сообщение Mirage » 04.06.2006 17:48:34

SovNarKom: Потому что будут ссылками на одну и ту же область памяти. Вообще знаете что значат модификаторы var и const и зачем они вообще нужны (по мне так const - лишний)?
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Сообщение SovNarKom » 04.06.2006 18:57:53

Mirage
Не будут

Я тебе ещё вещь скажу, все модификаторы нужны и полезны, const очень быстро работает, если даже использовать, например константу в коде, а не заводить переменную под неё сначало, а потом по var передавать.
SovNarKom
постоялец
 
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]

След.

Вернуться в Потрепаться

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 73

Рейтинг@Mail.ru