On Tuesday, 2 October 2012 at 08:17:33 UTC, Manu wrote:
On 7 August 2012 16:56, jerro <a...@a.com> wrote:


That said, almost all simd opcodes are directly accessible in std.simd.
There are relatively few obscure operations that don't have a representing
function.
The unpck/shuf example above for instance, they both effectively perform a
sort of swizzle, and both are accessible through swizzle!().


They aren't. Swizzle only takes one argument, so you cant use it to select elements from two vectors. Both unpcklps and shufps take two arguments.
Writing a swizzle with two arguments would be much harder.


Any usages I've missed/haven't thought of; I'm all ears.

I don't think it is possible to think of all usages of this, but for every simd instruction there are valid usages. At least for writing pfft, I found shuffling two vectors very useful. For, example, I needed a function that takes a small, square, power of two number of elements stored in vectors and bit-reverses them - it rearanges them so that you can calculate the new index of each element by reversing bits of the old index (for 16 elements using 4 element vectors this can actually be done using std.simd.transpose, but for AVX it was more efficient to make this function work on 64 elements). There are other places in pfft where I need to select elements from two vectors (for example, here https://github.com/jerro/pfft/blob/sine-transform/pfft/avx_float.d#L141 is the platform specific code for AVX).

I don't think this are the kind of things that should be implemented in std.simd. If you wanted to implement all such operations (for example bit reversing a small array) that somebody may find useful at some time, std.simd would need to be huge, and most of it would never be used.

I can imagine, I'll have a go at it... it's something I considered, but not
all architectures can do it efficiently.
That said, a most-efficient implementation would probably still be useful on all architectures, but for cross platform code, I usually prefer to encourage people taking another approach rather than supply a function that
is not particularly portable (or not efficient when ported).

One way to do it would be to do the following for every set of selected indices: go through all the two element one instruction operations, and check if any of them does exactly what you need, and use it if it does. Otherwise do something that will always work although it may not always be optimal. One option would be to use swizzle on both vectors to get each of the elements to their final index and then blend the two vectors together. For sse 1, 2 and 3 you would need to use xorps to blend them, so I guess this is one more place where you would need vector literals.

Someone who knows which two element shuffling operations the platform supports could still write optimal platform specific (but portable across compilers) code this way and for others this would still be useful to some degree (the documentation should mention that it may not be very efficient, though). But I think that it would be better to have platform specific APIs for platform specific code, as I said earlier in this thread.

Unfortunately I can't, at least not a clean one. Using string mixins would be one way but I think no one wants that kind of API in Druntime or Phobos.


Yeah, absolutely not.
This is possibly the most compelling motivation behind a __forceinline
mechanism that I've seen come up... ;)

 I'm already unhappy that
std.simd produces redundant function calls.

<rant> please  please please can haz __forceinline! </rant>


I agree that we need that.


Huzzah! :)

Walter opposes this, right? I wonder how we could convince him.

There's one more thing that I wanted to ask you. If I were to add LDC support to std.simd, should I just add version(LDC) blocks to all the functions? Sounds like a lot of duplicated code...

Reply via email to