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 // (...)? : Optional
A vector data type is an array of floating-point numbers with a maximum of 8 elements.
The operators __vc<operator name>
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.
Example
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
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.
Example
PROGRAM PLC_PRG VAR iOVS_REAL : INT; // Optimal vector size for REAL elements iOVS_LREAL : INT; // Optimal vector size for LREAL elements 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:

Operator __VCADD
The operator calculates the sum of two vectors.
Syntax
<vector variable> := <1st vector operand> __VCADD <2nd vector operand>;
Example of 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 of 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 of 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 of 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
<scalar variable> := <1st vector operand> __VCDOT <2nd vector operand> ;
Example of a 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 of a 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 of a 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 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
Example
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
Example
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.
Syntax
<vector variable> := __VCLOAD_REAL( <vector size>, <pointer to data of type REAL> ) ; <vector size> : 2 | 3 | 4 | 5| 6 | 7| 8
Example of vectorization
FUNCTION_BLOCK FB_LOAD VAR_INPUT END_VAR VAR_OUTPUT END_VAR VAR rData0 : REAL := 1.234; rData1: REAL := 5.678; rData2 : REAL := 9.123; pData: POINTER TO REAL := ADR(rData0); vcA : __VECTOR[3] OF REAL := __VCSET_REAL(3, 3, 3); END_VAR vcA := __VCLOAD_REAL(3, pData);
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.
Syntax
<vector variable> := __VCLOAD_REAL( <vector size>, <pointer to data of type LREAL> ); <number of vector elements> : 1 | 2 | 3 | 4 | 5| 6 | 7| 8
Example of vectorization
FUNCTION_BLOCK FB_LOAD VAR_INPUT END_VAR VAR_OUTPUT END_VAR VAR lrData0 : LREAL := -1.7976931348623158E+308; lrData1: LREAL := 1.6E+308; lrData2 : LREAL := 1.7E+308; lrData3 : LREAL := -1.6E+308; plData: POINTER TO LREAL := ADR(lrData0); vclA : __VECTOR[4] OF LREAL := __VCSET_LREAL(4, 4, 4, 4); END_VAR vclA := __VCLOAD_LREAL(4, plData);
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.
Syntax
__VCSTORE( <pointer to data>, <vector variable> );
Example of storage
FUNCTION_BLOCK FB_STORE VAR_INPUT END_VAR VAR_OUTPUT END_VAR VAR rData0 : REAL := 3; rData1: REAL := 3; rData2 : REAL := 3; pData: POINTER TO REAL := ADR(rData0); lrData0 : LREAL := 4; lrData1: LREAL := 4; lrData2 : LREAL := 4; lrData3 : LREAL := 4; plData: POINTER TO LREAL := ADR(lrData0); 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);