www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - vector Cross/Dot using core.simd?

reply "F i L" <witte2008 gmail.com> writes:
I'm trying to write a Cross and Dot function using 
core.simd.float4 and DMD

The C++ code looks like:

from: 
http://fastcpp.blogspot.com/2011/04/vector-cross-product-using-sse-code.html

   inline __m128 CrossProduct(__m128 a, __m128 b)
   {
     return _mm_sub_ps (
       _mm_mul_ps (
         _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1)),
         _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 1, 0, 2))
       ),
       _mm_mul_ps (
         _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 0, 2)),
         _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 0, 2, 1))
       )
     );
   }

I can see that core.simd.XMM supports a XMM.PSHUFB command I can 
use with __simd(), but I'm not sure how to go about translate the 
_MM_SHUFFLE() macro above.

For Dot product, I have a C# Mono.Simd function:

   public static Vector4f Dot(Vector4f a, Vector4f b)
   {
     var result = a * b;

     result = HorizontalAdd(result, result);
     result = HorizontalAdd(result, result);

     return result.X;
   }

And I have no idea what XMM command HorizontalAdd would translate 
to. But the Mono.Simd documentation says it performs:

   Vector4f HorizontalAdd(Vector4f a, Vector4f b)
   {
     return new Vector4f (
       (a.X + a.Y), (a.Z + a.W),
       (b.X + b.Y), (b.Z + b.W)
     );
   }

Does anyone know anything about SIMD operations that may be able 
to help me translate these functions into a D equivalent? I would 
very much appreciate your help.
Aug 11 2012
next sibling parent "F i L" <witte2008 gmail.com> writes:
On a side note, if I run the simple code:

     void16 a = 0, b = 0;
     void16 r = __simd(XMM.PSHUFB, a, b);
     writeln(r.array);

I get the following error:

     Internal error: e2ir.c 3817
Aug 11 2012
prev sibling next sibling parent Sean Cavanaugh <WorksOnMyMachine gmail.com> writes:
On 8/11/2012 8:23 PM, F i L wrote:
 I'm trying to write a Cross and Dot function using core.simd.float4 and DMD

 Does anyone know anything about SIMD operations that may be able to help
 me translate these functions into a D equivalent? I would very much
 appreciate your help.

Some reference: C++ simd intrinsic for dot product (requires SSE 4.1, very modern) _mm_dp_ps C++ simd instrinsic for horizontal add (requires SSE3, also reasonably modern) _mm_hadd_ps If you are on SSE2 (which is the base spec for x64) and also the minimum CPU target we use at work for commercial game development, you are stuck doing shuffles and adds for dot product, which effectively process these operations as scalar). Ideally one of the sides of the dot product is an array and you can vectorize the dot product itself (1 vector vs 4 others, or 4 v 4). This is common when setting up shapes like view frustum culling (point tested against 6-8 extruded planes in an array)
Aug 11 2012
prev sibling parent "F i L" <witte2008 gmail.com> writes:
Sean Cavanaugh wrote:
 Some reference:

 C++ simd intrinsic for dot product (requires SSE 4.1, very 
 modern)
 _mm_dp_ps

Good to know, thanks!
 C++ simd instrinsic for horizontal add (requires SSE3, also 
 reasonably modern)
 _mm_hadd_ps

Awesome, I see XMM.HADDPS (amoung others) in core.simd now, thanks again!
 If you are on SSE2 (which is the base spec for x64) and also 
 the minimum CPU target we use at work for commercial game 
 development, you are stuck doing shuffles and adds for dot 
 product, which effectively process these operations as scalar).

 Ideally one of the sides of the dot product is an array and you 
 can vectorize the dot product itself (1 vector vs 4 others, or 
 4 v 4).  This is common when setting up shapes like view 
 frustum culling (point tested against 6-8 extruded planes in an 
 array)

Thanks for the info.
Aug 12 2012