Quantcast

[SIMD] Pre-review questions

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[SIMD] Pre-review questions

Boost - Dev mailing list
Hello,

I have several questions regarding Boost.SIMD (for pre-review)

1. What is boost::simd::pack::storage_type I can't find it in
documentation. Is it the "native register" like __m128i for
pack<int,4>? If the answer is no, how do I get access to underlying
type?
2. I can't find in documentation how to performs casts between
different types: I see in docs split_low (actually after I grepped for
_mm_unpacklo) but I failed to find how to use one - there is no
documentation regarding conversion/casting operation or at least I
failed to find one.
3. Is there more convenient way to perform basic saturated operation
for example if I want to calc abs diff of two bs::pack<unsigned
char,16> values a,b I need to write

   bs::saturated_(be::minus)(a,b) + bs::saturated_(bs::minus)(b,a)

  It is quite inconvenient especially when most of operations you want
to do are saturated.

4. Why Boost.SIMD is restricted to C++11? Most of the stuff is
implementable withing C++2003, it severely limits the usability of the
library for existing projects that can't trivially switch to new C++
standard (and there are too many in the "real world" industry)

Thanks,
   Artyom

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [SIMD] Pre-review questions

Boost - Dev mailing list
On 26/03/2017 08:37, Artyom Beilis via Boost wrote:
> Hello,
>
> I have several questions regarding Boost.SIMD (for pre-review)
>
> 1. What is boost::simd::pack::storage_type I can't find it in
> documentation. Is it the "native register" like __m128i for
> pack<int,4>? If the answer is no, how do I get access to underlying
> type?

It is indeed as explained the concept pages :

https://developer.numscale.com/boost.simd/documentation/develop/struct_vectorized.html

No, usually you should not rely on this as :

  - it may be something else entirely depending on type/cardinal
including a pair of pack or a array o scalar when you're forced to
emulate some cases.

  - pack is automatically casted in the proper _m* type if you really
really need to write call to a platform specific intrinsic (which should
not be happening a lot anyway).

  - pack can also be constructed from or assigned a _m* type automatically.

What you may want is to know statically in generic contexts is if a pack
is actually stored "natively", something the has_native_storage
metafunction should tell you (doc is not up but will be next round of
updates).

> 2. I can't find in documentation how to performs casts between
> different types: I see in docs split_low (actually after I grepped for
> _mm_unpacklo) but I failed to find how to use one - there is no
> documentation regarding conversion/casting operation or at least I
> failed to find one.

The function you look for is pack_cast

https://developer.numscale.com/boost.simd/documentation/develop/group__group-bitwise_gade4bdae8c35c470224d94ba3b87ea36c.html#gade4bdae8c35c470224d94ba3b87ea36c

pack<float,8>

> 3. Is there more convenient way to perform basic saturated operation
> for example if I want to calc abs diff of two bs::pack<unsigned
> char,16> values a,b I need to write
>
>    bs::saturated_(be::minus)(a,b) + bs::saturated_(bs::minus)(b,a)
>
>   It is quite inconvenient especially when most of operations you want
> to do are saturated.

All functions in Boost.SIMD are function object. Decorators just wrap
them in a proper layer. So

auto sm = bs::saturated_(be::minus);
sm(a,b) + sm(b,a);

is the recommended way to do it.

Then in your specific example, you can use dist that do the proper
computation without calling the saturated costly version of minus. IF
you really want to handle saturation, in case of handling INT_MAX and
INT_MIN then call saturated_(dist).

Usually, we strongly advice the use of the highest-level possible
function instead of trying to just rewrite an old SSE* code using
one-for-one intrinsic mapping. Boost.SIMD wraps a lot of well known
tricks and optimization in high level version of said function in order
to give access to those to all users.

> 4. Why Boost.SIMD is restricted to C++11? Most of the stuff is
> implementable withing C++2003, it severely limits the usability of the
> library for existing projects that can't trivially switch to new C++
> standard (and there are too many in the "real world" industry)

Different reasons:

  - It was written like that initially and supporting old compilers was
not worth our time at the moment. C++11 helps us to write interface the
correct way without requiring to compile-time costly macros or similar
prehistoric tricks. It also enable us to have fancy trick like the "use
constexpr permutation function in shuffle" etc ...

  - we are in 2017 and most of our users - including our "real world
industry" customers - are OK with using C++11. Migrating to C++11 6
years after the standardization should not be a constraints as most
compilers now support it. We're proposing it to Boost, which is still,
in our mind, the one place to push forward the language not supporting
decades old compilers.

Best regards


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [SIMD] Pre-review questions

Boost - Dev mailing list
On Sun, Mar 26, 2017 at 3:05 PM, Joel FALCOU via Boost
<[hidden email]> wrote:

> On 26/03/2017 08:37, Artyom Beilis via Boost wrote:
>> 2. I can't find in documentation how to performs casts between
>> different types: I see in docs split_low (actually after I grepped for
>> _mm_unpacklo) but I failed to find how to use one - there is no
>> documentation regarding conversion/casting operation or at least I
>> failed to find one.
>
>
> The function you look for is pack_cast
>
> https://developer.numscale.com/boost.simd/documentation/develop/group__group-bitwise_gade4bdae8c35c470224d94ba3b87ea36c.html#gade4bdae8c35c470224d94ba3b87ea36c
>
> pack<float,8>
>

Still do you have examples or documentation for:

How do I cast for example low part or high part something like:

pack<unsigned byte,16> v;
pack<unsigned short,8> v1=cast_low(v); // note sometimes I indeed need
only low or only high part - not both
pack<unsigned short,8> v2=cast_high(v);
...
v=join_cast(v1,v2);  // short to byte

What is saturation policy: if I have unsigned short of value 257
casted to unsigned char would it cast to 1 or to 255?
How can I control the policy?

>> 3. Is there more convenient way to perform basic saturated operation
>> for example if I want to calc abs diff of two bs::pack<unsigned
>> char,16> values a,b I need to write
>>
>>    bs::saturated_(be::minus)(a,b) + bs::saturated_(bs::minus)(b,a)
>>
>>   It is quite inconvenient especially when most of operations you want
>> to do are saturated.
>
>
> All functions in Boost.SIMD are function object. Decorators just wrap them
> in a proper layer. So
>
> auto sm = bs::saturated_(be::minus);
> sm(a,b) + sm(b,a);
>
> is the recommended way to do it.
>

I see

> Then in your specific example, you can use dist that do the proper
> computation without calling the saturated costly version of minus. IF you
> really want to handle saturation, in case of handling INT_MAX and INT_MIN
> then call saturated_(dist).
>
> Usually, we strongly advice the use of the highest-level possible function
> instead of trying to just rewrite an old SSE* code using one-for-one
> intrinsic mapping. Boost.SIMD wraps a lot of well known tricks and
> optimization in high level version of said function in order to give access
> to those to all users.

I agree I searched for something like absdiff but didn't found the
"dist" function - but indeed it is better.

Thanks,
  Artyom

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [SIMD] Pre-review questions

Boost - Dev mailing list
On 26/03/2017 15:28, Artyom Beilis via Boost wrote:

> Still do you have examples or documentation for:
>
> How do I cast for example low part or high part something like:
>
> pack<unsigned byte,16> v;
> pack<unsigned short,8> v1=cast_low(v); // note sometimes I indeed need
> only low or only high part - not both
> pack<unsigned short,8> v2=cast_high(v);
> ...
> v=join_cast(v1,v2);  // short to byte
>
> What is saturation policy: if I have unsigned short of value 257
> casted to unsigned char would it cast to 1 or to 255?
> How can I control the policy?

If you only need part of it, it's not a cast, it's a split as cast
preserve cardinality of pack.

pack<unsigned byte,16> v;
pack<unsigned short,8> v1=split_low(v);
pack<unsigned short,8> v2=split_high(v);

and if you need both :

pack<unsigned byte,16> v;
auto vs = split(v);

and vs[0],vs[1] are the low and high parts respectively.

IIRC split has no saturation policy as saturation is what we use when
you go down the type. You can rebuild a smaller type using group or
saturated_(group).

You also have slice that slice a pack in two, keeping the type but
reducing the cardinal. combine do the reverse.

Considering this complexity, most of the common use-cases are handled by
pack_cast already, leaving direct call to split_* for more advanced usages.

As for the doc, thanks for raising an actual bug, the doc is not indeed
properly included. Will fix this.

Maybe a tutorial about pack_cast,slice,split,group and combine is indeed
needed.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Loading...