Vc 1.4.5
SIMD Vector Classes for C++
 
Loading...
Searching...
No Matches
simdize<T>

Detailed Description

Automatic type vectorization.

Struct Vectorization

The Vc::simdize<T> expression transforms the type T to a vectorized type. This requires the type T to be a class template instance or an arithmetic type.

Example: First, we declare a class template for a three-dimensional point. The template parameter T determines the type of the members and is float in the scalar (classical) case.

template <typename T> struct PointTemplate
{
T x, y, z;
// Declares tuple_size and makes the members accessible via get<N>(point), allowing
// the simdize implementation to convert between Point and PointV (see below).
PointTemplate(T xx, T yy, T zz) : x{xx}, y{yy}, z{zz} {};
// The following function will automatically be vectorized in the PointV type.
T distance_to_origin() const {
using std::sqrt;
return sqrt(x * x + y * y + z * z);
}
};
#define Vc_SIMDIZE_INTERFACE(MEMBERS_)
Definition simdize.h:1931

In the following we create a type alias for the scalar type, which simply means instantiating PointTemplate with float. The resulting type can then be transformed with simdize.

using Point = PointTemplate<float>; // A simple struct with three floats and two functions.
using PointV = Vc::simdize<Point>; // The vectorization of Point stores three float_v and thus
// float_v::size() Points.
SimdizeDetail::simdize< T, N, MT > simdize
Definition simdize.h:1910

The following shows a code example using the above Point and PointV types.

PointV pv = Point{0.f, 1.f, 2.f}; // Constructs a PointV containing PointV::size()
// copies of Point{0, 1, 2}.
for (int i = 1; i < int(pv.size()); ++i) {
assign(pv, i, {i + 0.f, i + 1.f, i + 2.f});
}
const Vc::float_v l = pv.distance_to_origin();
std::cout << l << '\n';
// prints [2.23607, 3.74166, 5.38516, 7.07107, 8.77496, 10.4881, 12.2066, 13.9284] with
// float_v::size() == 8
const Point most_distant = extract(pv, (l.max() == l).firstOne());
std::cout << '(' << most_distant.x << ", " << most_distant.y << ", " << most_distant.z << ")\n";
// prints (7, 8, 9) with float_v::size() == 8
The main vector class for expressing data parallelism.
Definition vector.h:126
S extract(const SimdizeDetail::Adapter< S, T, N > &a, size_t i)
Extracts and returns one scalar object from a SIMD slot at offset i in the simdized object a.
Definition simdize.h:1241
void assign(SimdizeDetail::Adapter< S, T, N > &a, size_t i, const S &x)
Assigns one scalar object x to a SIMD slot at offset i in the simdized object a.
Definition simdize.h:1221

Iterator Vectorization

Vc::simdize<Iterator> can also be used to turn an iterator type into a new iterator type with Vc::simdize<Iterator::value_type> as its value_type. Note that Vc::simdize<double> turns into Vc::Vector<double>, which makes it easy to iterate over a given container of builtin arithmetics using Vc::Vector.

void classic(const std::vector<Point> &data) {
using It = std::vector<Point>::const_iterator;
const It end = data.end();
for (It it = data.begin(); it != end; ++it) {
Point x = *it;
do_something(x);
}
}
void vectorized(const std::vector<float> &data) {
const It end = data.end();
for (It it = data.begin(); it != end; ++it) {
Vc::simdize<Point> x = *it; // i.e. PointV
do_something(x);
}
}

Macros

#define Vc_SIMDIZE_INTERFACE(MEMBERS_)
 

Typedefs

template<typename T , size_t N = 0, typename MT = void>
using simdize = SimdizeDetail::simdize<T, N, MT>
 

Functions

template<typename S , typename T , size_t N>
Adapter< S, T, N > shifted (const Adapter< S, T, N > &a, int shift)
 Returns a new vectorized object where each entry is shifted by shift.
 
template<typename S , typename T , std::size_t N>
void swap (Adapter< S, T, N > &a, std::size_t i, S &x)
 Swaps one scalar object x with a SIMD slot at offset i in the simdized object a.
 
template<typename A >
void swap (Scalar< A > &&a, typename A::scalar_type &b)
 std::swap interface to swapping one scalar object with a (virtual) reference to another object inside a vectorized object
 
template<typename A >
void swap (typename A::scalar_type &b, Scalar< A > &&a)
 std::swap interface to swapping one scalar object with a (virtual) reference to another object inside a vectorized object
 
template<class F , class = decltype(static_cast<Scalar>(std::declval<F>()( size_t())))>
 Adapter (F &&fun)
 Generator constructor {{{.
 

Macro Definition Documentation

◆ Vc_SIMDIZE_INTERFACE

#define Vc_SIMDIZE_INTERFACE ( MEMBERS_)
Value:
template <std::size_t N_> \
inline auto vc_get_()->decltype(std::get<N_>(std::tie MEMBERS_)) \
{ \
return std::get<N_>(std::tie MEMBERS_); \
} \
template <std::size_t N_> \
inline auto vc_get_() const->decltype(std::get<N_>(std::tie MEMBERS_)) \
{ \
return std::get<N_>(std::tie MEMBERS_); \
} \
enum : std::size_t { \
tuple_size = std::tuple_size<decltype(std::make_tuple MEMBERS_)>::value \
}

Declares functions and constants for introspection by the simdize functions. This allows e.g. conversion between scalar T and simdize<T>.

Parameters
MEMBERS_The data members of this struct/class listed inside extra parenthesis. The extra parenthesis are required because the macro would otherwise see a variable number of arguments.

Example:

template <typename T, typename U> struct X {
T a;
U b;
};
Note
You must use this macros in the public section of a class.

Definition at line 1931 of file simdize.h.

Typedef Documentation

◆ simdize

template<typename T , size_t N = 0, typename MT = void>
using simdize = SimdizeDetail::simdize<T, N, MT>

Vectorize/Simdize the given type T.

Template Parameters
TThis type must be a class template instance where the template arguments can be recursively replaced with their vectorized variant. If the type implements a specific interface for introspection and member modification, the resulting type can easily be constructed from objects of type T and scalar objects of type T can be extracted from it.
NThis value determines the width of the vectorization. Per default it is set to 0 making the implementation choose the value considering the compilation target and the given type T.
MTThis type determines the type to be used when replacing bool with Mask<MT>. If it is set to void the implementation choosed the type as smart as possible.
See also
Vc_SIMDIZE_STRUCT, Vc_SIMDIZE_MEMBER

Definition at line 1910 of file simdize.h.

Function Documentation

◆ shifted()

template<typename S , typename T , size_t N>
Adapter< S, T, N > shifted ( const Adapter< S, T, N > & a,
int shift )
inline

Returns a new vectorized object where each entry is shifted by shift.

This basically calls Vector<T>::shifted on every entry.

Parameters
aThe object to apply the shift on.
shiftThe number of entries to shift by.
Returns
a copy of a shifted by shift.

Definition at line 1069 of file simdize.h.

Referenced by Vc::SimdizeDetail::shifted().