   SSE compiler intrinsics and 16-byte align
  I am considering writing a version of my Vector, Matrix, and Quaternion classes using SSE when it is supported. Currently I am just taking the standard approach - operating on each element in serial. I was reading about SSE intrinsics and everything seemed pretty doable until I read that in order for _mm_load_ps to work the address must be 16-byte aligned. I can't think of any possible way that I could guarantee this in all places of my project that use these classes, especially the heap, without rewriting large portions, since I use these math classes all over the place. However, I also read about _mm_loadu_ps, which apparently operates on unaligned addresses, but is slower. My first question is, how much slower is the unaligned version, and could using it actually improve performance over the serial versions of my classes? Another possible solution I could see would be to do something likeif (d & 0xf == 0)_mm_load_ps( ... );else_mm_loadu_ps( ... );Of course, that would require a branch, so my guess is that would be pretty bad. Another possibility could befloat d[8] // allocate enough space to guarantee that some 16-byte alignment existsfloat * data_address = (float*)(((unsigned int)(data+4) | (0xf)) - 0xf); // find that 16-byte alignmentand actually store the data at data_address. But that of course requires at least 16 extra bytes per vector, and for 2d and 3d vectors that is over half the space they normally take.Does anyone have any suggestions? Or should I just not bother with SSE?   
Quote:Or should I just not bother with SSE?You might not want to. Depending on how heavy your math operations are you might not see the speed up you are looking for. Expecially considering that the SSE friendly formats aren't as friendly for other types of operations in all cases.Quote:Of course, that would require a branch, so my guess is that would be pretty bad. Another possibility could be....You should be using the intrinsic data types. Your vector should consist of only a __m128, that is NOT unioned with floats.You should be using _aligned_malloc(), and overload operator new() to use _aligned_malloc if you need (or use placement new).You should be using your compiler's intrinsic for alignment like _dllspec(align(16)) on any floats that you need to dump a __m128 into with a load or store intrinsic.Also, the fastest format is Structure of Arrays, not Array of Structures, so having:XXXXXXXX.....YYYYYYYY.....ZZZZZZZZ.....is better than havingXYZW XYZW XYZW.....for a large subset of math operations you want to do with SSE. So having individual "vectors" that are XYZW format, means only some operations (add,sub,multiply) will see speed up, while others(dot, cross, magnitude) might end up being slower.;  What KulSeran said.Quote:Original post by KulSeran_dllspec(align(16))At least on MSVC I think you're looking for __declspec(align(16)) [smile]   ;Quote:At least on MSVC I think you're looking for __declspec(align(16)) This is what I get for typing things from memory. You are totally right.;  Hm, that sounds pretty bad. I think I'll just stick with serial operations then.   ;Quote:Original post by GumgoHm, that sounds pretty bad. I think I'll just stick with serial operations then.That's my bet too. We just went through this process at work, and ultimately decided against SSE - it's impact on readability and usability can negatively effect developers in the general case. Instead, we profiled the code and rewrote one or two key places specifically to solve those cases.Best of luck.S.   