PDA

Prikaži potpunu verziju : Memory alignment i prosleđivanje po vrednosti - kolika je prepreka?


Geomaster
24.7.2011, 21:32
Jedno kratko pitanje.
Imam klasu sa nizom koji je definisan tako da se alignuje na 128-bitnoj (16-bajtnoj) granici. Ovo mi je potrebno zbog SSE optimizacija koje ovo zahtevaju ali znaju da budu i do 300% brže od običnih verzija. Međutim, otkrio sam da kompajler ne može da prosledi ovakvu klasu po vrednosti (što je i logično s obzirom na calling konvenciju). Primer:

class Test
{
public:
__attribute__ ((aligned (16))) float x[4];
};

void f(Test a) // ovde se pojavljuje greška
{
...
}
Sad, meni ovo ne predstavlja problem pošto uvek mogu da prosleđujem po referenci. Međutim, pošto pišem biblioteku, da li je ok da to bude tako tj. da se tipovi kao što su Matrix, Vector, Quaternion itd. ne mogu prosleđivati po vrednosti? Stvarno ne bih hteo da brišem alignment zato što bih izgubio dragocene dobitke u brzini, ali ako bi ovo predstavljalo neki veći problem krajnjem korisniku onda bih ipak ukinuo SSE podršku.

Belphegor
25.7.2011, 14:26
Nisam se jos "zezao" sa specificnim procesorskim instrukcijama i alignment-om tako da neznam konkretno zasto nece da funkcionise kad se prosledjujes po vrednosti. Evo jednog "objasnjenja" sa GameDev-a sto sam uspeo da nadjem za sad:



void Function( D3DXMATRIXA16 mx );


Parameters are passed by being pushed on the stack and popped off later, so the compiler can't guarantee the parameter (matrix) will be aligned on a 32-byte boundary. When passing by reference, on the other hand, the 'address' is what gets pushed on and popped off the stack, so there's no problem in alignment.


Offtopic: Izgleda da koristis GCC kompajler?

Geomaster
25.7.2011, 15:00
Jasno je meni zašto je tako nešto nemoguće (u stvari, tehnički bi bilo moguće da prvi parametar na steku bude na 16-bajtnoj granici ali ne verujem da se to koristi), ali ne znam da li bi ovo predstavljalo prepreku eventualnim korisnicima ove biblioteke?

Ne, koristim Microsoft Visual C++ kao IDE i debug kompajler, ali Release verzije uvek kompajlujem sa GCC-om (mingw na Windowsu) zato što radi bolje optimizaciju.

Belphegor
25.7.2011, 16:21
...ali ne znam da li bi ovo predstavljalo prepreku eventualnim korisnicima ove biblioteke?

Sad sam probao sa std::vector kontenerom:


#include <vector>

class vec4
{
public:
__m128 m;
};

class FooNode
{
public:
vec4 v;
};

int main()
{
FooNode fn;
std::vector<FooNode> v;
v.push_back(fn);

return 0;
}


output:

error C2719: '_Val': formal parameter with __declspec(align('16')) won't be aligned

EclipsE
25.7.2011, 18:52
Pa znas kako, i Bullet koristi alignment pa eto, dosta ljudi ga koristi :D

Sto se tice std::vectora, evo sta sam pronasao: http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=3638

Bullet uses btAlignedObjectArray as std::vector replacement due to the buggy Microsoft STL implementation.

Buggy Microsoft STL implementation? Microsoft, you have failed us again. :tapsh:

Belphegor
25.7.2011, 20:16
Ja ne bi' bas rekao da je "buggy", bolje je reci nedostatak (nije da ih branim nesto :D).
Vidim da predlazu drugu implementaciju STL-a ali me mrzi sad da probam :o.

Geomaster
25.7.2011, 21:48
Postoje i alternative, na primer korišćenje dinamičke alokacije aligned memorije pomoću posix_memalign ili _aligned_malloc (za Win), pa ću videti da to uradim (u konstruktoru alociram a u destruktoru samo dealociram, u slučaju da se koristi alignment).

A da, M$ stvarno ima faličnu implementaciju vektora, a o novim C++0x kontejnerima da ne govorim... Ali su IDE i debugger odlični.