Vektoroperationen werden nur auf 64-Bit-Prozessoren nativ unterstützt und bieten nur auf diesen einen Geschwindigkeitsvorteil. Das Datenblatt der Steuerung informiert Sie über den auf der Steuerung verwendeten Prozessor.
Aktuell werden Vektoroperationen auf den Plattformen x86-64Bit mit SSE2 und ARM64 mit NEON nativ unterstützt. Auf allen anderen Plattformen werden Vektoroperationen in einzelne Anweisungen übersetzt. Beispielsweise wird dann eine Vektoraddition mit mehreren einzelnen Additionen ausgeführt.
Die Befehlssatzerweiterungen der Prozessoren sind SIMD-Erweiterungen. SIMD (Single Instruction, Multiple Data) steht für eine Rechnerarchitektur, bei der mit einem Befehlsaufruf gleichzeitig mehrere gleichartige Datensätze parallel und damit schneller verarbeitet werden. Bei Vektoroperationen können dann beispielsweise 4 Zahlenpaare gleichzeitig addiert werden.
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
Ein Vektordatentyp ist ein Gleitpunktzahl-Array mit maximal 8 Elementen. Für diesen
Datentyp stehen die Operatoren __vc<operator name>
zur Verfügung. Damit können Sie Vektoroperationen ohne zusätzliche Funktionsaufrufe
implementieren.
Syntax bei Indexzugriff
<variable name>[ <index> ] <index> : 0 | 1 | 2| 3 | 4 | 5| 6 | 7
Beim Indexzugriff auf eine Vektorvariable können Sie auf ein einzelnes Element des Vektors zugreifen. Der Index beginnt bei 0 und geht bis <vector size> - 1.
Beispiel
PROGRAM PLC_PRG VAR vcA : __VECTOR[3] OF REAL; END_VAR vcA[0] := 1.1; vcA[1] := 2.2; vcA[2] := 3.3;
Optimale Vektorgröße bestimmen
Verwenden Sie als Vektorgröße die optimale, von Ihrem Zielsystem abhängige Vektorgröße, um möglichst effizienten Code zu programmieren.
Bei Zielsystemen, deren Rechnerarchitektur grundsätzlich für eine Vektorverarbeitung geeignet ist, ist es nicht ratsam Vektoren mit beliebiger Größe zu verwenden. Abhängig von der Art der Datenverarbeitung des Prozessors gibt es nämlich eine optimale Vektorgröße. Vektoren, die mit dieser Arraygröße deklariert werden, werden schnellstmöglich verarbeitet. Vektoren, die als größeres Array deklariert werden, haben keinen Geschwindigkeitsvorteil. Vektoren, die als kleineres Array deklariert werden, nutzen die Möglichkeiten des Prozessors nicht vollständig.
Sie können die optimale Größe zur Laufzeit abfragen. Die Informationen stehen Ihnen
in den Konstanten Constants.vcOptimalREAL
für Vektoren mit REAL
-Elementen und Constants.vcOptimalLREAL
für Vektoren mit LREAL
-Elementen zur Verfügung, Die Konstanten haben den Datentyp INT
. Wenn eine Konstanten als optimale Größe den Wert 1
zurückliefert, bedeutet das, dass das Zielsystem keine beschleunigte Vektorverarbeitung
zur Verfügung hat.
Beispiel
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;
Eine Applikation, die auf das Zielystem CODESYS Control Win V3 x64 geladen wird, liefert zur Laufzeit folgende Werte zurück:

Operator __VCADD
Der Operator berechnet die Summe zweier Vektoren.
Syntax
<vector variable> := <1st vector operand> __VCADD <2nd vector operand>;
Beispiel Addieren
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
Der Operator berechnet die Differenz zweier Vektoren.
Syntax
<vector variable> := <vector minuend> __VCSUB <vector subtrahend>;
Beispiel Subtrahieren
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
Der Operator berechnet das Produkt zweier Vektoren oder eines Skalars (Gleitpunktzahl) mit einem Vektor.
Syntax
<vector variable> := <1st vector operand> __VCMUL <2nd vector operand> | <scalar operand> __VCMUL <vector operand> | <vector operand> __VCMUL <scalar operand> ;
Beispiel Multiplizieren
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
Der Operator berechnet den Quotienten zweier Vektoren oder eines Vektors und eines Skalars.
Syntax
<vector variable> := <vector dividend> __VCDIV <vector divisor> | < vector dividend> __VCMUL <scalar divisor> ;
Beispiel Dividieren
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
Der Operator berechnet das Punktprodukt (Skalarprodukt) zweier Vektoren.
Syntax
<skalar variable> := <1st vector operand> __VCDOT <2nd vector operand> ;
Beispiel Punktprodukt
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
Der Operator berechnet die Quadratwurzel für jedes Element des Vektors.
Syntax
<vector variable> := __VCSQRT( <vector operand> );
Beispiel Quadratwurzel
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
Der Operator berechnet den maximalen Vektor zweier Vektoren. Dabei wird elementweise das Maximum bestimmt.
Syntax
<vector variable> := __VCMAX( <1st vector operand>, <2nd vector operand>);
Beispiel Maximumvektor
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
Der Operator berechnet den minimalen Vektor zweier Vektoren. Dabei wird elementweise das Minimum bestimmt.
Syntax
<vector variable> := __VCMIN( <1st vector operand>, <2nd vector operand>);
Beispiel Minimumvektor
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
Der Operator setzt alle Elemente eines Vektors in einer Anweisung. Die Elemente haben
den Datentyp REAL
.
Syntax
<vector variable> := __VCSET_REAL( <first literal>, ( < next literal> )+ ) ; ( ... )+ // number of elements have to match
Beispiel
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
Der Operator setzt alle Elemente eines Vektors auf einmal in einer Anweisung. Die
Elemente haben den Datentyp LREAL
.
Sie können den Operator überall dort verwendet werden, wo auch Variablen gültig sind, wie beispielsweise in Zuweisungen in Implementierungen oder als Parameter in Funktionsaufrufen.
Syntax
<vector variable> := __VCSET_LREAL( <first literal>, ( < next literal> )+ ) ; ( ... )+ // number of elements have to match
Beispiel
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
Der Operator interpretiert einen beliebigen Speicherbereich als Vektor. Das ist hilfreich,
um Vektorvariablen mit einem bestehenden Code zu verbinden. Der Operator benötigt
2 Parameter. Der erste Parameter gibt die Anzahl der Vektorelemente an. Der zweite
Parameter ist ein Pointer auf die REAL
-Daten.
Syntax
<vector variable> := __VCLOAD_REAL( <vector size>, <pointer to data of type REAL> ) ; <vector size> : 2 | 3 | 4 | 5| 6 | 7| 8
Beispiel Vektorisieren
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
Der Operator interpretiert einen beliebigen Speicherbereich als Vektor. Das ist hilfreich,
um Vektorvariablen mit einem bestehenden Code zu verbinden. Der Operator benötigt
2 Parameter. Der erste Parameter gibt die Anzahl der Vektorelemente an. Der zweite
Parameter ist ein Pointer auf die LREAL
-Daten.
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
Beispiel Vektorisieren
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
Der Operator speichert/kopiert den Inhalt des Vektors an die angegebene Speicheradresse. Die Anzahl und der Type der Elemente werden dabei automatisch von der Vektorvariablen übernommen.
Syntax
__VCSTORE( <pointer to data>, <vector variable> );
Beispiel Speichern
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);
Siehe auch