<div dir="ltr">On 19 July 2013 19:33, bearophile <span dir="ltr"><<a href="mailto:bearophileHUGS@lycos.com" target="_blank">bearophileHUGS@lycos.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class="im">Manu:<br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Interesting. Almost all his points are what we do already in D.<br>
Always nice to see others come to the same conclusions :)<br>
</blockquote>
<br></div>
While trying to write a multiplication of two complex numbers using SSE3 with LDC2 I have found about seven or more bugs, that I will discuss elsewhere. But regarding the syntax, in nice code like this D requires to add ".array" before all those subscripts (code adapted from Fog):<br>

<br>
<br>
double2 complexMult(in double2 a, in double2 b) pure nothrow {<br>
    double2 b_flip = [b.array[1], b.array[0]];<br>
    double2 a_im = [a.array[1], a.array[1]];<br>
    double2 a_re = [a.array[0], a.array[0]];<br>
    double2 aib = a_im * b_flip;<br>
    double2 arb = a_re * b;<br>
    return [arb.array[0] - aib.array[0], arb.array[1] + aib.array[1]];<br>
}<br>
<br>
<br>
A line like this:<br>
<br>
double2 b_flip = [b.array[1], b.array[0]];<br>
<br>
becomes something like:<br>
<br>
pshufd   $238,  %xmm1, %xmm3<br>
<br>
Similarly all the other lines become single instructions (but the last one, because LDC2 misses to use a addsubpd).<br>
<br>
I vaguely remember you saying that slow SIMD operations shouldn't have a too much short syntax to avoid giving an illusion of efficiency. But given that "often" the CPU executes such array subscripting and shuffling efficiently, isn't it nicer/enough to support a simpler syntax like this in D?<br>

<br>
double2 complexMult(in double2 a, in double2 b) pure nothrow {<br>
    double2 b_flip = [b[1], b[0]];<br>
    double2 a_im = [a[1], a[1]];<br>
    double2 a_re = [a[0], a[0]];<br>
    double2 aib = a_im * b_flip;<br>
    double2 arb = a_re * b;<br>
    return [arb[0] - aib[0], arb[1] + aib[1]];<br>
}<br></blockquote><div><br></div><div style>The point about eliminating the index operator is because it implies a vector->float cast.</div><div style>You want to perform a shuffle(/swizzle), but you are only really performing the operation incidentally.</div>
<div style>What you're really doing is casting a bunch of vector components to floats, and then rebuilding a vector, and LLVM can helpfully deal with that.</div><div style><br></div><div style>I would suggest calling a spade a spade and using a swizzle function to perform a swizzle, instead of code like what you wrote.</div>
<div style>Wouldn't this be better:</div><div style><br></div><div style>double2 complexMult(in double2 a, in double2 b) pure nothrow {<br>    double2 b_flip = b.yx; // or b.swizzle!"yx", if we don't want to include an opDispatch in the basic type<br>
    double2 a_im = a.yy;<br>    double2 a_re = a.xx;<br>    double2 aib = a_im * b_flip;<br>    double2 arb = a_re * b;</div><div style><br></div><div style>//    return [arb[0] - aib[0], arb[1] + aib[1]]; // this final line is tricky... it's not very portable.<br>
</div><div style><br></div><div style>    // Maybe:<br>    return select([-1, 0], arb-aib, arb+aib);</div><div style>    // Hopefully the x86 optimiser will generate the proper opcode. Or a bunch of other options; a multi-vector shuffle, shift, swizzle, interleave.</div>
<div style>}<br></div><div style><br></div><div style>I think that would be better. More portable, and it eliminates the code that implies a vector->float->vector cast sequence, which I maintain, should be syntactically discouraged at all costs.</div>
<div style>You don't want to be giving people bad ideas that it's reasonable code to write ;)</div></div></div></div>