Developer Guide and Reference

Contents

SDLT Primitives (SDLT_PRIMITIVE)

Primitives represent the data we want to work over in SIMD. They can be more than just data structures. As a C++ object, it can have its own methods that modify its data.
Rules:
  • Must be Plain Old Data (POD)
    • Has trivial copy constructor
    • Has trivial move constructor
    • Has trivial destructor
    • No virtual functions or virtual bases
  • No reference data members
  • No unions
  • No bit fields
  • No bool types
    • Comparison semantics not efficient in SIMD
    • Use 32-bit integer and compare against known values like 0 or 1 explicitly
  • Data members need to be public or declare
    SDLT_PRIMITIVE_FRIEND
    in the object's definition
Current limitations:
  • No pointer data members
  • No C++11 strongly typed enums—use integers instead.
  • No array based data members.
  • copy constructor and assignment operator (=) defined by individual member assignment—strongly encouraged to facilitate better code generation
They may seem like large restrictions, but often code can easily be re-factored to meet this requirement. For example:
class Point3d { // methods... protected: double v[3]; };
can be re-factored to have a public data member for each element in the array and update methods to use the
x
,
y
, and
z
data members rather than the array
v
.
class Point3d { public: // methods... double x; double y; double z; };
For better code generation, explicitly define a copy constructor and assignment operator (=) by individual member assignment.

SDLT_PRIMITIVE
Macro

Once an object meets the criteria above, we can consider it a Primitive type in SDLT. In order for Container's to import and export the Primitive, it has to understand its data layout. Unfortunately C++11 lacks compile time reflection, so the user must provide SDLT with a description of your structure's data layout. This is easily done with the SDLT_PRIMITIVE helper macro that accepts a struct type followed by a comma separated list of its data members.
SDLT_PRIMITIVE(STRUCT_NAME, DATA_MEMBER_1, ...)
Example Usage:
struct UserObject { float x; float y; double acceleration; int behavior; }; SDLT_PRIMITIVE(UserObject, x, y, acceleration, behavior)
An object must be declared as a Primitive before it can be used in a Container. However, built-in types like float, double, int, etc. do not need to be declared as a Primitive before use with a Container. Built-in's are automatically considered Primitives by SDLT.
Nested Primitives are supported, but the nested Primitive must be declared before the outer Primitive is. Example: Axis Aligned Bounding Box made up of two 3d points
struct Point3s { float x; float y; float z; }; struct AABB { Point3s topLeft; Point3s bottomRight; }; SDLT_PRIMITIVE(Point3s, x, y, z) SDLT_PRIMITIVE(AABB, topLeft, bottomRight)
Notice the
struct
definitions themselves do not derive from SDLT or use any of its nomenclature. This independence allows classes to be used in code not using SDLT and only code that does use SDLT Containers needs to see the Primitive declarations.

Product and Performance Information

1

Intel's compilers may or may not optimize to the same degree for non-Intel microprocessors for optimizations that are not unique to Intel microprocessors. These optimizations include SSE2, SSE3, and SSSE3 instruction sets and other optimizations. Intel does not guarantee the availability, functionality, or effectiveness of any optimization on microprocessors not manufactured by Intel. Microprocessor-dependent optimizations in this product are intended for use with Intel microprocessors. Certain optimizations not specific to Intel microarchitecture are reserved for Intel microprocessors. Please refer to the applicable product User and Reference Guides for more information regarding the specific instruction sets covered by this notice.

Notice revision #20110804