Vector Extensions - D Programming Language

Menu

- Learn
- Documentation
  - Language Reference
  - Library Reference
  - Command-line Reference
  - Feature Overview
  - Articles
- Downloads
- Packages
- Community
  - Blog
  - Orgs using D
  - Twitter
  - Forums
  - IRC
  - Community Discord
  - Wiki
  - GitHub
  - Issues
  - Get involved
  - Contributors
  - Foundation
  - Security Team
  - Donate
  - Sponsors
- Resources
  - Tour
  - Books
  - Tutorials
  - Tools
  - Editors
  - IDEs
  - run.dlang.io
  - Visual D
  - Acknowledgments
  - D Style
  - Glossary
  - Sitemap

Search
Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

# Vector Extensions

Contents

1. core.simd
   1. Properties
   2. Conversions
   3. Accessing Individual Vector Elements
   4. Conditional Compilation
2. X86 And X86_64 Vector Extension Implementation
   1. Vector Operation Intrinsics

CPUs often support specialized vector types and vector operations (a.k.a. media instructions). Vector types are a fixed array of floating or integer types, and vector operations operate simultaneously on them.

Specialized Vector types provide access to them.

The VectorBaseType must be a Static Array. The VectorElementType is the unqualified element type of the static array. The dimension of the static array is the number of elements in the vector.

Implementation Defined: Which vector types are supported depends on the target. The implementation is expected to only support the vector types and operations that are implemented in the target's hardware.
Rationale: Emulating unsupported vector types and operations can exhibit such poor performance that the user is likely better off selecting a different algorithm than relying on emulation.
Best Practices: Use the declarations in core.simd instead of the language Vector grammar.

## core.simd

Vector types and operations are introduced by importing core.simd:

    import core.simd;

Implementation Defined: These types and operations will be the ones defined for the architecture the compiler is targeting. If a particular CPU family has varying support for vector types, an additional runtime check may be necessary. The compiler does not emit runtime checks; those must be done by the programmer.
Implementation Defined: Depending on the target architecture, compiler flags may be required to activate support for SIMD types.

The types defined will all follow the naming convention:

    typeNN

where type is the vector element type and NN is the number of those elements in the vector type. The type names will not be keywords.

### Properties

Vector types have the property:

Vector Type Properties
Property | Description
--- | ---
.array | Returns static array representation

Vectors support the following properties based on the vector element type. The value produced is that of a vector of the same type with each element set to the value corresponding to the property value for the element type.

Integral Vector Type Properties
Property | Description
--- | ---
.min | minimum value
.max | maximum value

Floating Point Vector Type Properties
Property | Description
--- | ---
.epsilon | smallest increment to the value 1
.infinity | infinity value
.max | largest representable value that is not infinity
.min_normal | smallest representable value that is not 0
.nan | NaN value

### Conversions

Vector types of the same size (number_of_elements * size_of_element) can be implicitly converted among each other, this is done as a reinterpret cast (a type paint). Vector types can be cast to their VectorBaseType.

Integers and floating point values can be implicitly converted to their vector equivalents:

    int4 v = 7;
    v = 3 + v;   // add 3 to each element in v

### Accessing Individual Vector Elements

They cannot be accessed directly, but can be when converted to an array type:

    int4 v;
    (cast(int*)&v)[3] = 2;   // set 3rd element of the 4 int vector
    (cast(int[4])v)[3] = 2;  // set 3rd element of the 4 int vector
    v.array[3] = 2;          // set 3rd element of the 4 int vector
    v.ptr[3] = 2;            // set 3rd element of the 4 int vector

### Conditional Compilation

If vector extensions are implemented, the version identifier D_SIMD is set.

Whether a type exists or not can be tested at compile time with an IsExpression:

    static if (is(typeNN))
        ... yes, it is supported ...
    else
        ... nope, use workaround ...

Whether a particular operation on a type is supported can be tested at compile time with:

    float4 a,b;
    static if (__traits(compiles, a+b))
        ... yes, add is supported for float4 ...
    else
        ... nope, use workaround ...

For runtime testing to see if certain vector instructions are available, see the functions in core.cpuid.

A typical workaround for unsupported vector operations would be to use array operations instead:

    float4 a,b;
    static if (__traits(compiles, a/b))
        c = a / b;
    else
        c[] = a[] / b[];

## X86 And X86_64 Vector Extension Implementation

Implementation Defined:

The following describes the specific implementation of the vector types for the X86 and X86_64 architectures.

The vector extensions are currently implemented for the OS X 32 bit target, and all 64 bit targets.

core.simd defines the following types:

Vector Types
Type Name | Description | gcc Equivalent
--- | --- | ---
void16 | 16 bytes of untyped data | no equivalent
byte16 | 16 bytes | signed char __attribute__((vector_size(16)))
ubyte16 | 16 ubytes | unsigned char __attribute__((vector_size(16)))
short8 | 8 shorts | short __attribute__((vector_size(16)))
ushort8 | 8 ushorts | ushort __attribute__((vector_size(16)))
int4 | 4 ints | int __attribute__((vector_size(16)))
uint4 | 4 uints | unsigned __attribute__((vector_size(16)))
long2 | 2 longs | long __attribute__((vector_size(16)))
ulong2 | 2 ulongs | unsigned long __attribute__((vector_size(16)))
float4 | 4 floats | float __attribute__((vector_size(16)))
double2 | 2 doubles | double __attribute__((vector_size(16)))
void32 | 32 bytes of untyped data | no equivalent
byte32 | 32 bytes | signed char __attribute__((vector_size(32)))
ubyte32 | 32 ubytes | unsigned char __attribute__((vector_size(32)))
short16 | 16 shorts | short __attribute__((vector_size(32)))
ushort16 | 16 ushorts | ushort __attribute__((vector_size(32)))
int8 | 8 ints | int __attribute__((vector_size(32)))
uint8 | 8 uints | unsigned __attribute__((vector_size(32)))
long4 | 4 longs | long __attribute__((vector_size(32)))
ulong4 | 4 ulongs | unsigned long __attribute__((vector_size(32)))
float8 | 8 floats | float __attribute__((vector_size(32)))
double4 | 4 doubles | double __attribute__((vector_size(32)))

Note: for 32 bit gcc and clang, it's long long instead of long.

Supported 128-bit Vector Operators
Operator | void16 | byte16 | ubyte16 | short8 | ushort8 | int4 | uint4 | long2 | ulong2 | float4 | double2
--- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | ---
= | × | × | × | × | × | × | × | × | × | × | ×
+ | – | × | × | × | × | × | × | × | × | × | ×
- | – | × | × | × | × | × | × | × | × | × | ×
* | – | – | – | × | × | – | – | – | – | × | ×
/ | – | – | – | – | – | – | – | – | – | × | ×
& | – | × | × | × | × | × | × | × | × | – | –
| | – | × | × | × | × | × | × | × | × | – | –
^ | – | × | × | × | × | × | × | × | × | – | –
+= | – | × | × | × | × | × | × | × | × | × | ×
-= | – | × | × | × | × | × | × | × | × | × | ×
*= | – | – | – | × | × | – | – | – | – | × | ×
/= | – | – | – | – | – | – | – | – | – | × | ×
&= | – | × | × | × | × | × | × | × | × | – | –
|= | – | × | × | × | × | × | × | × | × | – | –
^= | – | × | × | × | × | × | × | × | × | – | –
== | – | × | × | × | × | × | × | × | × | × | ×
!= | – | × | × | × | × | × | × | × | × | × | ×
< | – | × | × | × | × | × | × | × | × | × | ×
<= | – | × | × | × | × | × | × | × | × | × | ×
>= | – | × | × | × | × | × | × | × | × | × | ×
> | – | × | × | × | × | × | × | × | × | × | ×
unary~ | – | × | × | × | × | × | × | × | × | – | –
unary+ | – | × | × | × | × | × | × | × | × | × | ×
unary- | – | × | × | × | × | × | × | × | × | × | ×

Supported 256-bit Vector Operators
Operator | void32 | byte32 | ubyte32 | short16 | ushort16 | int8 | uint8 | long4 | ulong4 | float8 | double4
--- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | ---
= | × | × | × | × | × | × | × | × | × | × | ×
+ | – | × | × | × | × | × | × | × | × | × | ×
- | – | × | × | × | × | × | × | × | × | × | ×
* | – | – | – | – | – | – | – | – | – | × | ×
/ | – | – | – | – | – | – | – | – | – | × | ×
& | – | × | × | × | × | × | × | × | × | – | –
| | – | × | × | × | × | × | × | × | × | – | –
^ | – | × | × | × | × | × | × | × | × | – | –
+= | – | × | × | × | × | × | × | × | × | × | ×
-= | – | × | × | × | × | × | × | × | × | × | ×
*= | – | – | – | – | – | – | – | – | – | × | ×
/= | – | – | – | – | – | – | – | – | – | × | ×
&= | – | × | × | × | × | × | × | × | × | – | –
|= | – | × | × | × | × | × | × | × | × | – | –
^= | – | × | × | × | × | × | × | × | × | – | –
== | – | × | × | × | × | × | × | × | × | × | ×
!= | – | × | × | × | × | × | × | × | × | × | ×
< | – | × | × | × | × | × | × | × | × | × | ×
<= | – | × | × | × | × | × | × | × | × | × | ×
>= | – | × | × | × | × | × | × | × | × | × | ×
> | – | × | × | × | × | × | × | × | × | × | ×
unary~ | – | × | × | × | × | × | × | × | × | – | –
unary+ | – | × | × | × | × | × | × | × | × | × | ×
unary- | – | × | × | × | × | × | × | × | × | × | ×

Operators not listed are not supported at all.

### Vector Operation Intrinsics

See core.simd for the supported intrinsics.

Application Binary Interface
Better C
Copyright © 1999-2023 by the D Language Foundation | Page generated by Ddoc on Sun Jan 1 07:32:13 2023