<div class="gmail_quote">On 5 August 2012 06:33, F i L <span dir="ltr"><<a href="mailto:witte2008@gmail.com" target="_blank">witte2008@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
core.simd vectors are limited in a couple of annoying ways. First, if I define:<br>
<br>
    @property pure nothrow<br>
    {<br>
        auto x(float4 v) { return v.ptr[0]; }<br>
        auto y(float4 v) { return v.ptr[1]; }<br>
        auto z(float4 v) { return v.ptr[2]; }<br>
        auto w(float4 v) { return v.ptr[3]; }<br>
<br>
        void x(ref float4 v, float val) { v.ptr[0] = val; }<br>
        void y(ref float4 v, float val) { v.ptr[1] = val; }<br>
        void z(ref float4 v, float val) { v.ptr[2] = val; }<br>
        void w(ref float4 v, float val) { v.ptr[3] = val; }<br>
    }<br>
<br>
Then use it like:<br>
<br>
    float4 a, b;<br>
<br>
    a.x = a.x + b.x;<br>
<br>
it's actually somehow faster than directly using:<br>
<br>
    a.ptr[0] += b.ptr[0];<br>
<br>
However, notice that I can't use '+=' in the first case, because 'x' isn't an lvalue. That's really annoying. Moreover, I can't assign a vector to anything other than a array of constant expressions. Which means I have to make functions just to assign vectors in a convenient way.<br>

<br>
    float rand = ...;<br>
    float4 vec = [rand, 1, 1, 1]; // ERROR: expected constant<br>
<br>
<br>
Now, none of this would be an issue at all if I could wrap core.simd vectors into custom structs... but doing that complete negates their performance gain (I'm guessing because of boxing?). It's a different between 2-10x speed improvements using float4 directly (depending on CPU), and only a few mil secs improvement when wrapping float4 in a struct.<br>

<br>
So, it's not my ideal situation, but I wouldn't mind at all having to use core.simd vector types directly, and moving things like dot/cross/normalize/etc to external functions, but if that's the case then I would _really_ like some basic usability features added to the vector types.<br>

<br>
Mono C#'s Mono.Simd.Vector4f, etc, types have these basic features, and working with them is much nicer than using D's core.simd vectors.<br>
</blockquote></div><br><div>I think core.simd is only designed for the lowest level of access to the SIMD hardware. I started writing std.simd some time back; it is mostly finished in a fork, but there are some bugs/missing features in D's SIMD support preventing me from finishing/releasing it. (incomplete dmd implementation, missing intrinsics, no SIMD literals, can't do unit testing, etc)</div>
<div><br></div><div>The intention was that std.simd would be flat C-style api, which would be the lowest level required for practical and portable use.</div><div>It's almost done, and it should make it a lot easier for people to build their own SIMD libraries on top. It supplies most useful linear algebraic operations, and implements them as efficiently as possible for other architectures than just SSE.</div>
<div>Take a look: <a href="https://github.com/TurkeyMan/phobos/blob/master/std/simd.d">https://github.com/TurkeyMan/phobos/blob/master/std/simd.d</a></div><div><br></div><div>On a side note, your example where you're performing a scalar add within a vector; this is bad, don't ever do this.</div>
<div>SSE (ie, x86) is the most tolerant architecture in this regard, but it's VERY bad SIMD design. You should never perform any component-wise arithmetic when working with SIMD; It's absolutely not portable.</div>
<div>Basically, a good rule of thumb is, if the keyword 'float' appears anywhere that interacts with your SIMD code, you are likely to see worse performance than just using float[4] on most architectures.</div><div>
Better to factor your code to eliminate any scalar work, and make sure 'scalars' are broadcast across all 4 components and continue doing 4d operations.</div><div><br></div><div>Instead of: @property pure nothrow float x(float4 v) { return v.ptr[0]; }</div>
<div>Better to use: @property pure nothrow float4 x(float4 v) { return swizzle!"xxxx"(v)<span style="font-size:medium;white-space:pre-wrap">;</span> }</div>