Intel® C++ Compiler Classic Developer Guide and Reference

ID 767249
Date 12/16/2022
Public

A newer version of this document is available. Customers should click here to go to the newest version.

Document Table of Contents

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);

NOTE:
The 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 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.

The following operations are supported for the aligned type.

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();

NOTE:
The 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.