Michael Dorgan
Michael Dorgan

Reputation: 12515

Is there any way to create a 16-byte aligned class that can be passed as a param

We have a (Numeric 3 float) vector class that I would love to align to 16-bytes in order to allow SIMD oerations. Using declspec to 16-byte align it causes a slew of C2719 errors (parameter': formal parameter with __declspec(align('#')) won't be aligned). If I can't pass around a vector aligned, what's the point? Even using a const reference to the vector is causing the compiler error which really annoys me.

Is there a way to do what I want here - get 16-byte class alignment while allowing struct passing without having to do some silly trickery to __m128 types?

Upvotes: 3

Views: 1559

Answers (5)

KSquared
KSquared

Reputation: 58

While the question is old, situation with VC++ compiler hasn't changed much, so perhaps, these notes will be of value to someone. 1) The simple fix to allow classes or structs with __declspec(align(X)) to be passed to functions is to pass by reference. Use consts as needed. 2) There is definitely a reason to use SIMD for vector algebra. I was able to speed up the animation and skinning pass in our engine by 20% by switching just quat multiply and quat rotate functions to SIMD. No alignment, no arrays. Just two functions that took float[4] params. For something that wasn't poorly written to begin with and to result in measurable FPS improvement, this is nothing to sneeze at. And since these are the sort of things that can be hard to optimize later, there is really no such thing as premature optimization for vector algebra. 3) If you make your vectors into a class, all of the excessive _mm_store_ps and _mm_load_ps instructions on the stack optimize out under /O2. So while gain of having a single add via SIMD might be negligible, if you have cases where you run several operations back to back, the resulting code is blazing fast.

Upvotes: 1

celion
celion

Reputation: 4004

There is a __declspec(passinreg) that's supported on Xbox360, but not in Visual Studio for Windows at the moment.

You can vote for the request to support the feature here: http://connect.microsoft.com/VisualStudio/feedback/details/381542/supporting-declspec-passinreg-in-windows

For vector arguments in our engine we use a VectorParameter typedef'ed to either const Vector or const Vector& depending on whether the platform supports passing by register.

Upvotes: 1

bames53
bames53

Reputation: 88215

If I can't pass around a vector aligned, what's the point?

__declspec(align(#)) does seem rather useless. C++11 has support for what you want; alignas appears to work in all the ways that __declspec(align(#)) is broken. For example, using alignas to declare your type will cause parameters of that type to be aligned.

Unfortunately Microsoft's compiler doesn't support standard alignment specifiers yet, and the only compiler I know of that does is Clang, which has limited support for Windows.

Anyway, I just wanted to point out that C++ has this feature and it will probably be available to you eventually. Unless you can move to another platform then for now you're probably best off with not passing parameters by value, as others have mentioned

Upvotes: 3

TonyK
TonyK

Reputation: 17124

Surely you don't need to pass the array by value? Pass a pointer to the 16-byte-aligned array instead. Or have I misunderstood something?

Upvotes: 1

Jason R
Jason R

Reputation: 11716

You're not likely to get much of a benefit from using SIMD unless you're operating on a bunch of these 3-dimensional vector structures at a time, in which case you would probably pass them in an array, which you could align as you need to. The other case where you might obtain some benefit from SIMD is if you're doing a lot of computations on each vector and you can parallelize the operations on the three channels. In that case, then doing some manual manipulation at the beginning of a function to coax it into a __m128 type might still afford you some benefit.

Upvotes: 6

Related Questions