Visible to Intel only — GUID: GUID-308A4694-3F48-437E-994C-B8375058BB29
Visible to Intel only — GUID: GUID-308A4694-3F48-437E-994C-B8375058BB29
Number Representation
When specifying extents, positions inside of, or bounds of a container, numeric values can be represented three different ways: fixed, aligned, and int. Fixed is most precise and int is least precise. It is advised to use as precise specification as possible. The compiler may optimize better with more information.
Fixed
Represent a numerical constant whose value specified at compile time.
template <int NumberT> class fixed;
If offsets applied to index values inside a SIMD loop are known at compile time, then the compiler can use that information. For example, to maintain aligned access, if boundary is fixed and known to be aligned when accessing underlying data layout. When multiple accesses are happening near each other, the compiler will have the opportunity to detect which accesses occur in the same cache lines and potentially avoid prefetching the same cache line repeatedly. Additionally, if the start of an iteration space is known at compile time, if it's a multiple of the SIMD lane count, the compiler could skip generating a peel loop. Whenever possible, fixed values should be used over aligned or arbitrary integer values.
Although std::integral_constant<int> provides the same functionality, the library defines own type to provide overloaded operators and avoid collisions with any other code's interactions with std::integral_constant<int>.
The following table provides information about the template arguments for fixed.
Template Argument | Description |
---|---|
int Number T |
The numerical value the fixed will represent. |
The following table provides information about the members of fixed.
Member | Description |
---|---|
static constexpr int value = NumberT |
The numerical value known at compile-time. |
constexpr operator value_type() const |
Returns: The numerical value |
constexpr value_type operator()() const; |
Returns: The numerical value |
Constant expression arithmetic operators +,- (both unary and binary), * and / are defined for type sdlt::fixed<> and will be evaluated at compile-time.
The suffix _fixed is a C++11 user-defined equivalent literal. For example, 1080_fixed is equivalent to fixed<1080>. Consider the readability of the two samples below.
foo3d(fixed<1080>(), fixed<1920>());
versus
foo3d(1080_fixed, 1920_fixed);
Aligned
Represent integer value known at compile time to be a multiple of an IndexAlignment.
template <int IndexAlignmentT> class aligned;
If you can tell the compiler that you know that an integer will be a multiple of known value, then, when combined with a loop index inside a SIMD loop, the compiler can use that information to maintain aligned access when accessing underlying data layout.
Internally, the integer value is converted to a block count, where:
block_count = value/IndexAlignmentT;
Overloaded math operations can then use that aligned block count as needed. The value() is represented by AlignmentT*block_count allowing the compiler to prove that the value() is a multiple of AlignmentT, which can utilize alignment optimizations.
The following table provides information about the template arguments for aligned.
Template Argument | Description |
---|---|
int IndexAlignmentT |
The alignment the user is stating that the number is a multiple of. IndexAlignmentT must be a power of two. |
The following table provides information about the types defined as members of aligned.
Member Type | Description |
---|---|
typedef int value_type |
The type of the numerical value. |
typedef int block_type |
The type of the block_count. |
The following table provides information about the members of aligned.
Member | Description |
---|---|
static const int index_alignment |
The IndexAlignmentT value. |
aligned() |
Constructs empty (uninitialized) object |
explicit aligned(value_type) |
Constructs computing block_count=a_value/IndexAlignmentT. |
aligned(const aligned& a_other) |
Constructs copying block_count from a_other. a_other must have same IndexAlignmentT. |
template<int OtherAlignment> explicit aligned(const aligned& other) |
Constructs computing block_count optimized by avoiding computing other.value(). Must have IndexAlignmentT of a_other < IndexAlignmentT and other.value() be multiple of IndexAlignmentT. |
template<int OtherAlignment> aligned(const aligned& other) |
Constructs computing block_count with a multiply instead of divide. Must have IndexAlignmentT of a_other > IndexAlignmentT |
static aligned from_block_count(block_type block_count) |
Creates an instance of aligned avoiding any math by directly using supplied block_count |
value_type value() const |
Computes the value represented by the aligned. Returns: aligned_block_count()*IndexAlignmentT |
operator value_type() |
Conversion to int. Returns: value() |
block_type aligned_block_count() const |
Conversion to int. Returns: The block count |
Operation | Description |
---|---|
operator *(int), commutative |
Scale value. Returns: aligned<IndexAlignmentT > |
operator *(fixed<V>), commutative |
Scales IndexAlignment by 2^M and value by K. Must have V=2^M*K (V is a multiple of a power of 2). Returns: aligned<IndexAlignmentT*(2^M)> |
operator *(aligned<OtherAl>) |
Scales IndexAlignment by OtherAl and block_count by argument. Returns: aligned<IndexAlignmentT*OtherAl> |
int operator/(fixed<IndexAlignmentT>) |
Returns: aligned_block_count() |
int operator/(fixed<-IndexAlignmentT>) |
Returns: -aligned_block_count(); |
int operator/(fixed<V>) |
Must have abs(V)>IndexAlignmentT && IndexAlignmentT%V==0. Returns: aligned_block_count()/(V/IndexAlignmentT) |
int operator/(fixed<V>) |
Must have abs(V) < IndexAlignmentT && V%IndexAlignmentT==0 Returns: aligned_block_count()*(IndexAlignmentT/V) |
aligned operator -() |
Returns: Same type aligned for negated value. |
aligned operator -(const aligned &) const |
Returns: Same type aligned for value of difference. |
template<int OtherAl> aligned<?> operator -(const aligned<OtherAl>&) const |
Difference with other alignment. Behavior and returned alignment type depend on relation between alignments of operands. Returns: Value for difference as lower of incoming alignments |
template<int V> aligned<?> operator -(const fixed<V> &) const |
Difference with fixed value. Behavior and returned alignment type depend on relation between alignments of aligned<> operand and the value of V. Returns: Adjusted aligned value of a difference |
aligned operator +(const aligned &)const |
Returns: Same type aligned for value of sum |
template<int OtherAl> aligned<?> operator +(const aligned<OtherAl>&) const |
Sum with other alignment. Behavior and returned alignment type depend on relation between alignments of operands. Returns: Value for sum as lower of incoming alignments |
template<int V> aligned<?> operator +(const fixed<V> &) const |
Sum with fixed value. Behavior and returned alignment type depend on relation between alignments of aligned<> operand and the value of V. Returns: Adjusted aligned value of a sum. |
template<int OtherAl> aligned operator +=(const aligned<OtherAl> &) const |
Increments value for the aligned object if IndexAlignmentT is compatible with OtherAl Returns: Aligned with incremented value. |
template<int OtherAl> aligned operator -=(const aligned<OtherAl> &) const |
Decrements value for the aligned object if IndexAlignmentT is compatible with OtherAl Returns: Same type aligned with decremented value. |
template<int OtherAl> aligned operator *=(const aligned<OtherAl> &) const |
Multiplies value for the aligned object if IndexAlignmentT is compatible with OtherAl. Returns: Same type aligned with multiplied value. |
template<int OtherAl> aligned operator /=(const aligned<OtherAl> &) const |
Divides value for the aligned object if IndexAlignmentT is compatible with OtherAl Returns: Same type aligned with divided value. |
int
Represents an arbitrary integer value. In interfaces where fixed<> and aligned<> values supported you may also use plain old integer value. It provides least information among these three and so least facilitates compiler optimizations.
- aligned_offset
Represent an integer based offset whose value is a multiple of an IndexAlignment specified at compile time. #include <sdlt/aligned_offset.h> - fixed_offset
Represent an integer based offset whose value specified at compile time. #include <sdlt/fixed_offset.h>