Оптимизированное вычисление длины вектора

OlegXXL

Помогите оптимизировать следующий код:
struct point
{
public: float x, y, z;
};
inline float length(point a, point b)
{
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z);
}
P.S. Как вы поняли речь идет о С++
P.P.S. Корень я не забыл, мне нужен квадрат длины.
P.P.P.S. Можно сделать asm-вставку (если конечно так будет быстрее работать)

Ivan8209

hypot, GSL.
---
"Vyroba umelych lidi, slecno, je tovarni tajemstvi."

okunek

Имхо компиляторы с хорошими оптимизаторами (в частности, интеловский) сами соптимизируют этот код по максимуму

Dasar

> Можно сделать asm-вставку (если конечно так будет быстрее работать)
под какой процессор?

OlegXXL

x86
совместимо должно быть и с Intel и с AMD

Dasar

> совместимо должно быть и с Intel и с AMD
тогда ничего хорошего в асм-е все равно не напишешь.

tamusyav

Ну почему же? Если требовать процессор не ниже PIII/Athlon64, то через SSE можно сделать и побыстрее. Если добавить четвертую координату.

Ivan8209

Да, и всё это съестся на накладных расходах.
---
...Я работаю антинаучным аферистом...

OlegXXL

Ну тогда ладно, забейте. Я думал что это можно оптимизировать просто и чтоб в несколько раз быстрее было.

Realist

Попробуй point передавать по ссылке, а не по значению.
Ну и переименуй length в length2 что-ли, ибо некошерно

Chupa

warning: людям без чувства юмора дальше не читать

#include <stdio.h>

#include <xmmintrin.h>

typedef __v4sf point;

static __inline float __attribute____always_inline__ length2(point a, point b)
{
float r;
asm (
"subps %2,%1\n"
"mulps %1,%1\n"
"movhlps %1,%2\n"
"addps %2,%1\n"
"movlhps %1,%2\n"
"shufps $0x03,%1,%2\n"
"addps %2,%1\n"
"movss %1%0)\n"
: : "r"(&r "x"(a "x"(b) : "memory");
return r;
}

int main
{
float f;
point a, b;

a = __extension__ (__v4sf){0.0f, 0.0f, 0.0f, 0.0f};
b = __extension__ (__v4sf){1.0f, 1.0f, 1.0f, 0.0f};

f = length2(a,b);

printf("r = %f\n", f);

return 0;
}

gcc 1.c -msse

durka82

Если уж так важна скорость, мб стоит перейти на целочисленную арифметику?
Если 32-х битных представлений числа недостаточно - стоит использовать 64-х битное (но надо, чтобы и ось и проц тоже были 64-х битными - реализация 64-х битных целых на 32-х и на 64-х битных системах по скорости отличается на порядок).
Не знаю точно, мб последнее время что-то изменилось, но Интел вроде как так и не довела свой 64-х битный режим до скорости 64-х битных процов АМД.

Olyalyau

Нафиг так сложно? Горизонтальные операции в данном случае лучше вообще не использовать, если SSE или SSE2. (AT&T синтаксис, GNU C++):

inline
float
distance (point const & a,
point const & b) throw
{
point c;
asm ("movaps\t%1, %%xmm0\n\t"
"subps\t%2, %%xmm0\n\t"
"mulps\t%%xmm0, %%xmm0\n\t"
"movaps\t%%xmm0, %0"
: "=m" (c)
: "m" (a "m" (b;
return c.x + c.y + c.z;
}

А если SSE3, то есть же горизонтальное сложение (всё равно я бы таким вариантом не пользовался). Тем более что он требует обязательного забивания 0 в четвёртый float.

inline
float
distance (point const & a,
point const & b) throw
{
point c;
asm ("movaps\t%1, %%xmm0\n\t"
"subps\t%2, %%xmm0\n\t"
"mulps\t%%xmm0, %%xmm0\n\t"
"haddps\t%%xmm0, %%xmm0\n\t"
"haddps\t%%xmm0, %%xmm0\n\t"
"movaps\t%%xmm0, %0"
: "=m" (c)
: "m" (a "m" (b;
return c.x;
}

Кстати, о четвёртом float'е:

struct point
{
public: float x, y, z;
private:
float pad;

public:
point throw :
pad (0)
{
}

point (float const x,
float const y,
float const z) throw :
x (x
y (y
z (z
pad (0)
{
}
} __attribute__ aligned (16;

И наличие выравнивания на 16 байт обязательно, иначе будет непредсказуемо валиться на movaps'ах.
Можно, конечно, вместо них использовать movups'ы, но они медленнее.
И вообще, всё это от лукавого. Для того, чтобы понять стоит ли заморачиваться и будет ли с этого выгода, надо проводить натурные испытания на программе в целом. Не говоря уж о том, что есть Intel'овский компилятор, который умеет векторизовать код автоматически.

Olyalyau

hypot

Лажа. hypot двумерный, а человеку нужна трёхмерная функция.
GSL
Тоже лажа. GSL не является оптимизированной.

Chupa

> Нафиг так сложно?
warning был специально для таких как ты
> И вообще, всё это от лукавого.
именно
Оставить комментарий
Имя или ник:
Комментарий: