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
|
---|---|
| The numerical value the fixed will represent.
|
The following table provides information about the members of
fixed
.
Member
| Description
|
---|---|
| The numerical value known at compile-time.
|
| Returns: The numerical value
|
| 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);
This content is specific to C++; it does not apply to
The
DPC++
.sdlt::fixed<NumberT>
type supersedes the deprecated
sdlt::fixed_offset<OffsetT>
type found in SDLT v1. It is strongly advised to use
sdlt::fixed<NumberT>
. However, in this release, a template alias is provided mapping
sdlt::fixed_offset<OffsetT>
onto
sdlt::fixed<NumberT>
.
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 easily 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
|
---|---|
| 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
|
---|---|
| The type of the numerical value.
|
| The type of the
block_count .
|
The following table provides information about the members of
aligned
.
Member
| Description
|
---|---|
| The
IndexAlignmentT value.
|
| Constructs empty (uninitialized) object
|
| Constructs computing
block_count=a_value/IndexAlignmentT .
|
| Constructs copying
block_count from
a_other .
a_other must have same
IndexAlignmentT.
|
| Constructs computing
block_count optimized by avoiding computing other.value(). Must have
IndexAlignmentT of a_other <
IndexAlignmentT and other.value() be multiple of
IndexAlignmentT .
|
| Constructs computing
block_count with a multiply instead of divide. Must have
IndexAlignmentT of a_other >
IndexAlignmentT |
| Creates an instance of
aligned avoiding any math by directly using supplied
block_count |
| Computes the value represented by the aligned.
Returns: aligned_block_count()*IndexAlignmentT |
| Conversion to
int .
Returns: value() |
| Conversion to
int .
Returns: The block count
|
aligned
type.
Operation
| Description
|
---|---|
| Scale value.
Returns:
aligned<IndexAlignmentT > |
| 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)> |
| Scales
IndexAlignment by
OtherAl and
block_count by argument.
Returns: aligned<IndexAlignmentT*OtherAl> |
| Returns: aligned_block_count()
|
| Returns: -aligned_block_count();
|
| Must have
abs(V)>IndexAlignmentT && IndexAlignmentT%V==0 .
Returns: aligned_block_count()/(V/IndexAlignmentT) |
| Must have
abs(V) < IndexAlignmentT && V%IndexAlignmentT==0
Returns: aligned_block_count()*(IndexAlignmentT/V) |
| Returns: Same type aligned for negated value.
|
| Returns: Same type aligned for value of difference.
|
| 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
|
| 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
|
| Returns: Same type aligned for value of sum
|
| 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
|
| 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.
|
| Increments value for the aligned object if
IndexAlignmentT is compatible with
OtherAl Returns: Aligned with incremented value.
|
| Decrements value for the aligned object if
IndexAlignmentT is compatible with
OtherAl Returns: Same type aligned with decremented value.
|
| Multiplies value for the aligned object if
IndexAlignmentT is compatible with
OtherAl .
Returns: Same type aligned with multiplied value.
|
| Divides value for the aligned object if
IndexAlignmentT is compatible with
OtherAl Returns: Same type aligned with divided value.
|
This content is specific to C++; it does not apply to
The
DPC++
.sdlt::aligned<>
type supersedes the deprecated
sdlt::aligned_offset<>
type found in SDLT v1. It is strongly advised to use
sdlt::aligned<>
, however in this release a template alias is provided mapping
sdlt::aligned_offset<>
onto
sdlt::aligned<>
.
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.