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

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

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

Sniper
постоялец
Сообщения: 472
Зарегистрирован: 28.05.2005 13:02:42

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

Сообщение Sniper »

Во время перевода libSIMD обнаружил, что процедура типа

Код: Выделить всё

procedure simd_vecs3_sub(a, b:TVector3f; var c:TVector3f);assembler;

быстрее

Код: Выделить всё

function simd_vecs3_sub(a, b: TVector3f):TVector3f;assembler;

Причём не просто быстрее а в 2 (два)! раза
Почему?
Аватара пользователя
STAKANOV
энтузиаст
Сообщения: 1069
Зарегистрирован: 14.05.2006 21:26:24
Откуда: Зеленоград

Сообщение STAKANOV »

В 2 раза это если процедура маленькая. А так советую собрать оба варианта с опцией -a и сразу будет видна разница. Хотя подозреваю, что без оптимизации тут не обошлось (вроде должно быть наоборот).
SovNarKom
постоялец
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]
Контактная информация:

Сообщение SovNarKom »

В смысле??? Всю жизнь процедуры быстрее функций были,
под возвращаемое значение выделяется память
Sniper
постоялец
Сообщения: 472
Зарегистрирован: 28.05.2005 13:02:42

Сообщение Sniper »

Вот они родимые:

Код: Выделить всё

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 раз.
Аватара пользователя
Иван Шихалев
энтузиаст
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург
Контактная информация:

Сообщение Иван Шихалев »

Правильно. Память выделяется не внутри функции, а снаружи... Затем еще идет передача данных из Result в переменную, которой значение функции присваивается...
Sniper
постоялец
Сообщения: 472
Зарегистрирован: 28.05.2005 13:02:42

Сообщение Sniper »

Вот вопрос в тему: Как вообще от этого Result отбиться?При чём begin/end использовать не получится...
Последний раз редактировалось Sniper 31.05.2006 16:41:08, всего редактировалось 1 раз.
Аватара пользователя
Иван Шихалев
энтузиаст
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург
Контактная информация:

Сообщение Иван Шихалев »

В смысле "отбиться"? Возвращать только простые значения, которые влазят в регистры...
Sniper
постоялец
Сообщения: 472
Зарегистрирован: 28.05.2005 13:02:42

Сообщение Sniper »

ну не могу же я написать

Код: Выделить всё

movq  [simd_vecs3_sub_1], mm0
movd  [simd_vecs3_sub_1+8], mm1

%)

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

В разные регисты Delphi и FPC рассовывают переменные?
Ответ: в одинаковые
Последний раз редактировалось Sniper 31.05.2006 17:07:28, всего редактировалось 1 раз.
SovNarKom
постоялец
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]
Контактная информация:

Сообщение SovNarKom »

Вот такой код работать должен

Код: Выделить всё

function geteipasebx : pointer; assembler;
asm
 mov ebx, esp
 ret
end;

Возвращает, как я понимаю в ebx...
Mirage
энтузиаст
Сообщения: 880
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia
Контактная информация:

Сообщение Mirage »

Sniper: По-моему ты такой вопрос уде задавал на этом форуме.:)
Функция возвращает такой результат как вектор через стек (целое обычно через EAX - зависит от calling convention). А процедура (с var параметром) изменяет непосредственно память. Тут есть подводный камень - если процедура должна изменять данные, а они еще должны быть ею использованы в оригинальном виде (например такое имеет место при перемножении матриц или матрицы на вектор), то получишь глюки. Причем глюки трудновычислимые, т.к. с виду-то все в порядке.:)
Аватара пользователя
STAKANOV
энтузиаст
Сообщения: 1069
Зарегистрирован: 14.05.2006 21:26:24
Откуда: Зеленоград

Сообщение STAKANOV »

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

Можно об этом подробней?
Mirage
энтузиаст
Сообщения: 880
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia
Контактная информация:

Сообщение Mirage »

А чего собственно непонятного?
Допустим вектор множится на матрицу:

Код: Выделить всё

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 на переменную, то были бы такие же глюки. Так что правильно делают, что через стек.
SovNarKom
постоялец
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]
Контактная информация:

Сообщение SovNarKom »

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

Почему?! :shock:
Mirage
энтузиаст
Сообщения: 880
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia
Контактная информация:

Сообщение Mirage »

SovNarKom: Потому что будут ссылками на одну и ту же область памяти. Вообще знаете что значат модификаторы var и const и зачем они вообще нужны (по мне так const - лишний)?
SovNarKom
постоялец
Сообщения: 389
Зарегистрирован: 28.05.2005 10:37:39
Откуда: Воронеж [vrn] [36]
Контактная информация:

Сообщение SovNarKom »

Mirage
Не будут

Я тебе ещё вещь скажу, все модификаторы нужны и полезны, const очень быстро работает, если даже использовать, например константу в коде, а не заводить переменную под неё сначало, а потом по var передавать.
Ответить