public:
int DotProduct_Vector4_f32(Vector4_f32 *SrcA, Vector4_f32 *SrcB, f32 *Dest, size_t Len);
private:
int DotProduct_Vector4_f32_NoVec(Vector4_f32 *SrcA, Vector4_f32 *SrcB, f32 *Dest, size_t Len);
int DotProduct_Vector4_f32_SSE (Vector4_f32 *SrcA, Vector4_f32 *SrcB, f32 *Dest, size_t Len);
int DotProduct_Vector4_f32_SSE2 (Vector4_f32 *SrcA, Vector4_f32 *SrcB, f32 *Dest, size_t Len);
int DotProduct_Vector4_f32_SSE3 (Vector4_f32 *SrcA, Vector4_f32 *SrcB, f32 *Dest, size_t Len);
The user programmer can only call DotProduct_Vector4_f32() which decides if the chip is capable of using SSE, and then it calls the appropriate specific function. If no vectorized function is available, then it calls the NoVec version, which is written in straight C++, and is as optimized as the compiler makes it, but it wont be processor specific unless you set the compiler flags for GCC to make it specific. Another issue with SSE SIMD is alignment. Most of the SSE instructions that access memory require the memory be aligned on a 16 byte boundry. The default malloc() and new only allocs on a 4 or 8 byte boundry usually. So this class also provides a Malloc() and Free() function. The Malloc will always provide an address that is 32 byte aligned, but it must be deallocated using the provided Free() as well (or _mm_free()). But even if you call the public function with an unaligned bit of memory, no problem. It just uses the NoVec version. (because even though the math would be faster with SSE, the unaligned loads have shown to be too slow to use, you're better off without vectorizing) Below are some benchmarks Ive done with the only two chips available to me. A P4 2ghz and an AMD64 4200. The P4 has SSE2, the AMD has SSE3. Some of the benchmarks in the P4 have a (4) in them, thats the UNSUPPORTED_ERROR that happens if you somehow force a call of a function that your chip doesn't support. But that impossible outside of my test code, cause they are all private. Those are NVec trying to call an SSE3 function on an SSE2 P4. As you can see, some things speed up by alot, some barly at all, but at least they arn't slower. (except my dot product... dunno what Im doing wrong there) Also AMD is clearly superior [grin].
P4, 2ghz, Windows, mingw 3.4.4
Copy_Void - NoVec(0): 0.16644s SSE1(0): 0.08773s ratio: 1.89715
MemC(0): 0.16209s ratio: 1.02684
Copy_f32 - NoVec(0): 0.15348s SSE1(0): 0.07080s ratio: 2.16791
Add_s8 - NoVec(0): 0.06297s SSE2(0): 0.01501s ratio: 4.19570
Add_s16 - NoVec(0): 0.06013s SSE2(0): 0.02526s ratio: 2.38015
Add_s32 - NoVec(0): 0.05942s SSE2(0): 0.03558s ratio: 1.66991
Add_s64 - NoVec(0): 0.23151s SSE2(0): 0.04226s ratio: 5.47808
Add_f32 - NoVec(0): 0.06437s SSE1(0): 0.02644s ratio: 2.43460
Add_f64 - NoVec(0): 0.06274s SSE2(0): 0.04324s ratio: 1.45099
Sub_s8 - NoVec(0): 0.06174s SSE2(0): 0.01665s ratio: 3.70858
Sub_s16 - NoVec(0): 0.05396s SSE2(0): 0.04232s ratio: 1.27482
Sub_s32 - NoVec(0): 0.06556s SSE2(0): 0.03301s ratio: 1.98598
Sub_s64 - NoVec(0): 0.24717s SSE2(0): 0.04825s ratio: 5.12274
Sub_f32 - NoVec(0): 0.06099s SSE1(0): 0.02866s ratio: 2.12811
Sub_f64 - NoVec(0): 0.06350s SSE2(0): 0.04641s ratio: 1.36825
Mul_s8 - NoVec(0): 0.20123s
Mul_s16 - NoVec(0): 0.21326s SSE2(0): 0.02868s ratio: 7.43717
Mul_s32 - NoVec(0): 0.08393s
Mul_s64 - NoVec(0): 0.55440s
Mul_f32 - NoVec(0): 0.07070s SSE1(0): 0.02631s ratio: 2.68736
Mul_f64 - NoVec(0): 0.07513s SSE2(0): 0.04152s ratio: 1.80949
Div_f32 - NoVec(0): 0.71638s SSE1(0): 0.15914s ratio: 4.50145
SSE2(0): 0.02852s ratio: 25.11886
Div_f64 - NoVec(0): 0.71739s SSE2(0): 0.56716s ratio: 1.26488
Vector_Matrix_Mul_f32 - NoVec(0): 0.68920s SSE1(0): 0.23659s ratio: 2.91303
Matrix_Mul_f32 - NoVec(0): 0.05337s
DotProduct_Vector4_f32 - NoVec(0): 0.18801s SSE1(0): 0.45078s ratio: 0.41707
SSE2(0): 0.31374s ratio: 0.59925
SSE3(4): 0.00143s ratio: 131.39008
CrossProduct_Vector4_As3_f32 - NoVec(0): 0.28419s
Pythag_Point4_f32 - NoVec(0): 0.78027s SSE2(0): 0.15287s ratio: 5.10421
SSE3(4): 0.00215s ratio: 362.16559
DegToRad_f32 - NoVec(0): 0.06527s SSE1(0): 0.03107s ratio: 2.10098
RadToDeg_f32 - NoVec(0): 0.06727s SSE1(0): 0.02729s ratio: 2.46482
NormalizeRadian_f32 - NoVec(0): 1.39405s SSE2(0): 0.07361s ratio: 18.93737
Normalize_Vector4_f32 - NoVec(0): 3.52634s SSE2(0): 0.42094s ratio: 8.37729
SSE3(4): 0.00158s ratio: 2227.00865
Normalize_Vector4_As3_f32 - NoVec(0): 2.74994s SSE2(0): 0.41086s ratio: 6.69320
SSE3(4): 0.00159s ratio: 1734.54167
Sin_f32 - NoVec(0): 3.19895s SSE1(0): 0.16969s ratio: 18.85165
Cos_f32 - NoVec(0): 3.14094s SSE1(0): 0.17623s ratio: 17.82270
Tan_f32 - NoVec(0): 3.78208s SSE1(0): 0.16602s ratio: 22.78061
AMD 4200x2, Linux gentoo amd64, gcc 3.4.3
Copy_Void - NoVec(0): 0.03698s SSE1(0): 0.04002s ratio: 0.92414
MemC(0): 0.03668s ratio: 1.00815
Copy_f32 - NoVec(0): 0.16726s SSE1(0): 0.06289s ratio: 2.65954
Add_s8 - NoVec(0): 0.04277s SSE2(0): 0.01932s ratio: 2.21314
Add_s16 - NoVec(0): 0.04274s SSE2(0): 0.02595s ratio: 1.64692
Add_s32 - NoVec(0): 0.04319s SSE2(0): 0.03743s ratio: 1.15391
Add_s64 - NoVec(0): 0.04304s SSE2(0): 0.05437s ratio: 0.79156
Add_f32 - NoVec(0): 0.04464s SSE1(0): 0.03387s ratio: 1.31795
Add_f64 - NoVec(0): 0.04304s SSE2(0): 0.05444s ratio: 0.79066
Sub_s8 - NoVec(0): 0.04278s SSE2(0): 0.03171s ratio: 1.34933
Sub_s16 - NoVec(0): 0.05569s SSE2(0): 0.02605s ratio: 2.13765
Sub_s32 - NoVec(0): 0.04337s SSE2(0): 0.03763s ratio: 1.15234
Sub_s64 - NoVec(0): 0.04316s SSE2(0): 0.05457s ratio: 0.79078
Sub_f32 - NoVec(0): 0.04353s SSE1(0): 0.03408s ratio: 1.27739
Sub_f64 - NoVec(0): 0.04322s SSE2(0): 0.05468s ratio: 0.79038
Mul_s8 - NoVec(0): 0.05691s
Mul_s16 - NoVec(0): 0.05353s SSE2(0): 0.02615s ratio: 2.04688
Mul_s32 - NoVec(0): 0.06347s
Mul_s64 - NoVec(0): 0.05693s
Mul_f32 - NoVec(0): 0.04352s SSE1(0): 0.03410s ratio: 1.27644
Mul_f64 - NoVec(0): 0.04322s SSE2(0): 0.05466s ratio: 0.79078
Div_f32 - NoVec(0): 0.18276s SSE1(0): 0.11666s ratio: 1.56657
SSE2(0): 0.03411s ratio: 5.35777
Div_f64 - NoVec(0): 0.23127s SSE2(0): 0.21440s ratio: 1.07869
Vector_Matrix_Mul_f32 - NoVec(0): 0.39048s SSE1(0): 0.29176s ratio: 1.33836
Matrix_Mul_f32 - NoVec(0): 0.01752s
DotProduct_Vector4_f32 - NoVec(0): 0.09569s SSE1(0): 0.19165s ratio: 0.49928
SSE2(0): 0.24406s ratio: 0.39207
SSE3(0): 0.13233s ratio: 0.72311
CrossProduct_Vector4_As3_f32 - NoVec(0): 0.12821s
Pythag_Point4_f32 - NoVec(0): 0.27117s SSE2(0): 0.08501s ratio: 3.18966
SSE3(0): 0.07029s ratio: 3.85759
DegToRad_f32 - NoVec(0): 0.03737s SSE1(0): 0.01875s ratio: 1.99312
RadToDeg_f32 - NoVec(0): 0.03724s SSE1(0): 0.01832s ratio: 2.03286
NormalizeRadian_f32 - NoVec(0): 0.51535s SSE2(0): 0.05654s ratio: 9.11448
Normalize_Vector4_f32 - NoVec(0): 0.80477s SSE2(0): 0.26697s ratio: 3.01448
SSE3(0): 0.17059s ratio: 4.71758
Normalize_Vector4_As3_f32 - NoVec(0): 0.66702s SSE2(0): 0.28358s ratio: 2.35211
SSE3(0): 0.17074s ratio: 3.90655
Sin_f32 - NoVec(0): 0.97305s SSE1(0): 0.12248s ratio: 7.94434
Cos_f32 - NoVec(0): 1.07045s SSE1(0): 0.10753s ratio: 9.95522
Tan_f32 - NoVec(0): 1.51840s SSE1(0): 0.12262s ratio: 12.38287