Skip to main content

Data Type: __VECTOR

Note

Vector operations are supported natively only on 64-bit processors and offer a performance advantage only on these processors. The data sheet of the controller provides information about the processor used on the controller.

Currently, vector operations on the x86/64-bit platforms with SSE2 and ARM64 with NEON are supported natively. On all other platforms, vector operations are translated into individual statements. For example, vector addition is then executed with multiple single addition operations.

The command set extensions of the processors are SIMD extensions. SIMD (Single Instruction, Multiple Data) describes a computer architecture in which multiple data sets of the same type are processed simultaneously in parallel and therefore faster with one command call. In vector operations, for example, 4 pairs of numbers can then be added at the same time.

Syntax

<variable name> :  __VECTOR[ <vector size> ] OF <element type> := <initialization> ;

<vector size> : 1 |2 | 3 | 4 | 5| 6 | 7| 8
<element type> : REAL | LREAL

The initialization of variables is optional.

A vector data type is an array of floating-point numbers with a maximum of 8 elements. The __vc<operator name> operators are available for this data type. You can use these to implement vector operations without additional function calls.

Syntax for index access

<variable name>[ <index> ]
<index> : 0 | 1 | 2| 3 | 4 | 5| 6 | 7

When indexing a vector variable, you can access a single element of the vector. The index starts at 0 and goes until <vector size> - 1.

PROGRAM PLC_PRG
VAR
        vcA : __VECTOR[3] OF REAL;
END_VAR

vcA[0] := 1.1;
vcA[1] := 2.2;
vcA[2] := 3.3;

Determining the optimal vector size

Tip

Use the optimal vector size depending on your target system as the vector size in order to program the most efficient code possible.

For target systems whose computer architecture is generally suitable for vector processing, we do not recommend using vectors of arbitrary size. There is an optimal vector size depending on the type of data processing of the processor. Vectors that are declared with this array size are processed as quickly as possible. Vectors that are declared as a larger array do not have an advantage in speed. Vectors that are declared as smaller arrays do not take full advantage of the processor's capabilities.

You can query the optimal size at runtime. You can find the information in the constants Constants.vcOptimalREAL (for vectors with REAL elements) and Constants.vcOptimalLREAL (for vectors with LREAL elements). The constants have the LREAL data type. If a constant returns the value 1 as the optimal value, then this means that accelerated vector processing is not available for the target system.

PROGRAM PLC_PRG
VAR
        iOVS_REAL : INT; // Optimal vector size for REAL eleements
        iOVS_LREAL : INT; // Optimal vector size for LREAL eleements
END_VAR

iOVS_REAL := Constants.vcOptimalREAL;
iOVS_LREAL := Constants.vcOptimalLREAL;

An application that is loaded on the CODESYS Control Win V3 x64 target system returns the following values at runtime:

_cds_img_read_optimal_vector_size.png

Operator: __VCADD

The operator calculates the sum of two vectors.

Syntax

<vector variable> := <1st vector operand> __VCADD <2nd vector operand>;
Example 241. Addition
FUNCTION_BLOCK FB_ADD
VAR
    vcA : __VECTOR[3] OF REAL := __VCSET_REAL(3, 3, 3);
    vcB : __VECTOR[3] OF REAL := __VCSET_REAL(1, 2, 3);
    vcResult : __VECTOR[3] OF REAL;
END_VAR
vcResult := vcA __VCADD vcB;


Operator: __VCSUB

The operator calculates the difference between two vectors.

Syntax

<vector variable> := <vector minuend> __VCSUB <vector subtrahend>;
Example 242. Subtraction
FUNCTION_BLOCK FB_SUB
VAR
    vcA : __VECTOR[3] OF REAL := __VCSET_REAL(3, 3, 3);
    vcB : __VECTOR[3] OF REAL := __VCSET_REAL(1, 2, 3);
    vcResult0 : __VECTOR[3] OF REAL;
    vcResult1 : __VECTOR[3] OF REAL;
END_VAR
vcResult0 := vcA __VCSUB vcB;
vcResult1 := vcB __VCSUB vcA;


Operator: __VCMUL

The operator calculates the product of two vectors or a scalar (floating-point number) and a vector.

Syntax

<vector variable> := <1st vector operand> __VCMUL <2nd vector operand> | <scalar operand> __VCMUL <vector operand> | <vector operand> __VCMUL <scalar operand> ;
Example 243. Multiplication
FUNCTION_BLOCK FB_MUL
VAR
    rScalar : REAL := 1.1;
    vcA : __VECTOR[3] OF REAL;
    vcB : __VECTOR[3] OF REAL;
    vcResult0 : __VECTOR[3] OF REAL;
    vcResult1 : __VECTOR[3] OF REAL;
    vcResult2 : __VECTOR[3] OF REAL;
END_VAR
vcResult0 := vcA __VCMUL vcB;
vcResult1 := rScalar __VCMUL vcB;
vcResult2 := vcA __VCMUL 3.3;


Operator: __VCDIV

The operator calculates the quotient of two vectors or a vector and a scalar.

Syntax

<vector variable> := <vector dividend> __VCDIV <vector divisor> | < vector dividend> __VCMUL <scalar divisor> ;
Example 244. Division
FUNCTION_BLOCK FB_DIV
VAR
    iScalar : INT := 3;
    rScalar : REAL := 1.5;
    vcA : __VECTOR[3] OF REAL := __VCSET_REAL(3, 3, 3);
    vcB : __VECTOR[3] OF REAL := __VCSET_REAL(1, 2, 3);
    vcResult0 : __VECTOR[3] OF REAL;
    vcResult1 : __VECTOR[3] OF REAL;
    vcResult2 : __VECTOR[3] OF REAL;
END_VAR
vcResult0 := vcA __VCDIV vcB;
// ERROR CODE vcResult1 := rScalar __VCDIV vcB;
// ERROR CODE vcResult1 := iScalar __VCDIV vcB;
// ERROR CODE vcResult1 := 3.3 __VCDIV vcB;
vcResult2 := vcA __VCDIV 1.5;
vcResult2 := vcA __VCDIV iScalar;
vcResult2 := vcA __VCDIV rScalar;


Operator: __VCDOT

The operator calculates the dot product (scalar product) of two vectors.

Syntax

<skalar variable> := <1st vector operand> __VCDOT <2nd vector operand> ;
Example 245. Dot product
FUNCTION_BLOCK FB_DOT
VAR
    rResult : REAL;
    vcA : __VECTOR[3] OF REAL := __VCSET_REAL(3, 3, 3);
    vcB : __VECTOR[3] OF REAL := __VCSET_REAL(1, 2, 3);
END_VAR
rResult := vcA __VCDOT vcB; // = 18


Operator: __VCSQRT

The operator calculates the square root of each element in the vector.

Syntax

<vector variable> := __VCSQRT( <vector operand> );
Example 246. Square root
FUNCTION_BLOCK FB_SQRT
VAR
    vcA : __VECTOR[3] OF REAL := __VCSET_REAL(4, 9, 16);
    vcResult0 : __VECTOR[3] OF REAL;
END_VAR
vcResult0 := __VCSQRT(vcA);


Operator: __VCMAX

The operator calculates the maximum vector of two vectors. The maximum is determined element by element.

Syntax

<vector variable> := __VCMAX( <1st vector operand>, <2nd vector operand>);
Example 247. Maximum vector
FUNCTION_BLOCK FB_MAX
VAR
    vcA : __VECTOR[3] OF REAL := __VCSET_REAL(3, 3, 3);
    vcB : __VECTOR[3] OF REAL := __VCSET_REAL(1, 2, 6);
    vcResult0 : __VECTOR[3] OF REAL;
END_VAR
vcResult0 := __VCMAX(vcA, vcB);


Operator: __VCMIN

The operator calculates the minimum vector of two vectors. The minimum is determined element by element.

Syntax

<vector variable> := __VCMIN( <1st vector operand>, <2nd vector operand>);
Example 248. Example of a minimum vector
FUNCTION_BLOCK FB_MIN
VAR
    vcA : __VECTOR[3] OF REAL := __VCSET_REAL(3, 3, 3);
    vcB : __VECTOR[3] OF REAL := __VCSET_REAL(1, 2, 6);
    vcResult0 : __VECTOR[3] OF REAL;
END_VAR
vcResult0 := __VCMIN(vcA, vcB);


Operator: __VCSET_REAL

The operator sets all elements of a vector in a statement. The elements have the REAL data type.

Syntax

<vector variable> := __VCSET_REAL( <first literal>, ( < next literal> )+ ) ;
( ... )+ // number of elements have to match
FUNCTION_BLOCK FB_SET
VAR
    vcA : __VECTOR[3] OF REAL := __VCSET_REAL(3, 3, 3);
    vcB : __VECTOR[3] OF REAL := __VCSET_REAL(1, 2, 3);
END_VAR
vcA := __VCSET_REAL(4, 4, 4);
vcB := __VCSET_REAL(1.1, 2.2, 3.3);

Operator: __VCSET_LREAL

The operator sets all elements of a vector at once in a statement. The elements have the LREAL data type.

They can be used wherever variables are valid, such as in assignments in implementations or as parameters in function calls.

Syntax

<vector variable> := __VCSET_LREAL( <first literal>, ( < next literal> )+ ) ;
( ... )+ // number of elements have to match
FUNCTION_BLOCK FB_SET
VAR
    vclA : __VECTOR[3] OF LREAL := __VCSET_LREAL(3, 3, 3);
    vclB : __VECTOR[3] OF LREAL := __VCSET_LREAL(1, 2, 3);
END_VAR
vclA := __VCSET_LREAL(-1.7976931348623158E+308, 0.0, 1.7976931348623158E+308);
vclB := __VCSET_LREAL(-1.7976931348623158E+308, 0.0, 1.7976931348623158E+308);

Operator: __VCLOAD_REAL

The operator interprets any arbitrary memory area as a vector. This is helpful for connecting vector variables to existing code. The operator requires 2 parameters. The first parameter indicates the number of vector elements. The second parameter is a pointer to the REAL data.

Important

__VCLOAD_REAL(<n>,<ptr>) reads <n> successive REAL values at the <ptr> address. If there are less than <n> values at this address, then this can cause the controller to crash or read unwanted memory.

Syntax

<vector variable> := __VCLOAD_REAL( <vector size>, <pointer to data of type REAL> ) ;
<vector size> : 2 | 3 | 4 | 5| 6 | 7| 8
Example 249. Vectorizing
FUNCTION_BLOCK FB_LOAD
VAR_INPUT
END_VAR
VAR_OUTPUT
END_VAR
VAR
    rData : ARRAY[0..2] OF REAL := [1.234, 5.678, 9.123];
    vcA : __VECTOR[3] OF REAL := __VCSET_REAL(3, 3, 3);
END_VAR

vcA := __VCLOAD_REAL(3, ADR(rData[0]));


Operator: __VCLOAD_LREAL

The operator interprets any arbitrary memory area as a vector. This is helpful for connecting vector variables to existing code. The operator requires 2 parameters. The first parameter indicates the number of vector elements. The second parameter is a pointer to the LREAL data.

Important

__VCLOAD_LREAL (<n>,<ptr>) reads <n> successive LREAL values at the <ptr> address. If there are less than <n> values at this address, then this can cause the controller to crash or read unwanted memory.

Syntax

<vector variable> := __VCLOAD_LREAL( <vector size>, <pointer to data of type LREAL> );
<number of vector elements> : 1 | 2 | 3 | 4 | 5| 6 | 7| 8
Example 250. Vectorizing
FUNCTION_BLOCK FB_LOAD
VAR_INPUT
END_VAR
VAR_OUTPUT
END_VAR
VAR
    rData : ARRAY[0..3] OF LREAL := [-1.7976931348623158E+308, 1.6E+308, 1.7E+308, -1.6E+308];
    vcA : __VECTOR[3] OF LREAL := __VCSET_LREAL(1, 2, 3);
END_VAR

vcA := __VCLOAD_LREAL(3, ADR(rData[0]));


Operator: __VCSTORE

The operator saves/copies the contents of the vector to the specified memory address. The number and the types of elements are automatically applied from the vector variables.

Important

__VCSTORE(<n>,<ptr>) writes <n> successive values at the <ptr> address. If there are less than <n> values at this address, then this can cause the controller to crash or write unwanted memory.

Syntax

__VCSTORE( <pointer to data>, <vector variable> );
Example 251. Save
FUNCTION_BLOCK FB_STORE
VAR_INPUT
END_VAR
VAR_OUTPUT
END_VAR
VAR
        rData : ARRAY[0..2] OF REAL := [1, 2, 3];
        pData: POINTER TO REAL := ADR(rData[0]);

        lrData : ARRAY [0..3] OF LREAL := [1, 2, 3, 4];
        plData: POINTER TO LREAL := ADR(lrData[0];


        vcA : __VECTOR[3] OF REAL := __VCSET_REAL( 1.234, 5.678, 9.123);
        vclA : __VECTOR[4] OF LREAL := __VCSET_LREAL(-1.7976931348623158E+308, 1.6E+308, 1.7E+308, -1.6E+308);
END_VAR

__VCSTORE(pData, vcA);
__VCSTORE(plData, vclA);