Vektoroperationen werden nur von 64-Bit-Prozessoren nativ unterstützt und bieten nur mit diesen Prozessoren einen Leistungsvorteil. Informationen zum Prozessor finden Sie im Datenblatt Ihrer Steuerung.
Vektoroperationen auf x86/64-Bit-Plattformen mit SSE2 und ARM64 mit NEON werden nativ unterstützt. Auf anderen Plattformen werden Vektoroperationen in einzelne Anweisungen untergliedert. So wird eine Vektoraddition z. B. durch die Ausführung mehrerer Einzeladditionsoperationen ausgeführt.
Die Befehlssatzerweiterungen der Prozessoren sind SIMD-Erweiterungen (Single Instruction, Multiple Data). SIMD beschreibt eine Computerarchitektur, in der zahlreiche Datensätze desselben Typs über einen Befehlsaufruf simultan verarbeitet werden. In Vektoroperationen ist es beispielsweise möglich, vier Zahlenpaare gleichzeitig hinzuzufügen.
<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 entspricht einem Array aus Gleitkommazahlen mit maximal 8 Elementen. Die Operatoren __vc<operator name>
sind für diesen Datentyp verfügbar. Sie ermöglichen Ihnen die Implementierung von Vektoroperationen ohne zusätzliche Funktionsaufrufe.
<variable name>[ <index> ]
<index> : 0 | 1 | 2| 3 | 4 | 5| 6 | 7
Durch die Indizierung einer Vektorvariablen können Sie auf ein einzelnes Element des Vektors zugreifen. Der Indexbereich reicht von 0 bis <Vektorgröße> - 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;
Für die Programmierung eines effizienten Codes müssen Sie die geeignete Vektorgröße für Ihr Zielsystem ermitteln und verwenden.
Bei Zielsystemen mit Computerarchitektur, die sich in der Regel für eine Vektorverarbeitung eignet, hat es sich nicht bewährt, Vektoren einer beliebigen Größe einzusetzen. Für jeden Prozessor ist je nach Typ der Datenverarbeitung eine optiomale Vektorgröße verfügbar. Für Vektoren dieser Größe wird die Verarbeitungszeit optimiert. Es ergibt sich kein Geschwindigkeitsvorteil aus Vektoren, die als größeres Array deklariert werden. Vektoren, die als kleinere Arrays deklariert werden, schöpfen die Prozessorkapazität nicht vollständig aus.
Sie können die optimale Größe zur Laufzeit mit den folgenden Konstanten des Datentyps INT abfragen:
Constants.vcOptimalREAL
: Für Vektoren mit REAL-Elementen.
Constants.vcOptimalLREAL
: Für Vektoren mit LREAL-Elementen.
Der Rückgabewert 1
bedeutet, dass die beschleunigte Vektorverarbeitung für das Zielsystem nicht verfügbar ist.
Beispiel:
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;
Der Operator berechnet die Summe zweier Vektoren.
Syntax:
<vector variable> := <1st vector operand> __VCADD <2nd vector operand>;
Beispiel für eine Additionsoperation:
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;
Der Operator berechnet die Differenz zwischen zwei Vektoren.
Syntax:
<vector variable> := <vector minuend> __VCSUB <vector subtrahend>;
Beispiel für eine Subtraktionsoperation:
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;
Der Operator berechnet das Produkt zweier Vektoren oder eines Skalars (Gleitkommazahl) und eines Vektors.
Syntax:
<vector variable> := <1st vector operand> __VCMUL <2nd vector operand> | <scalar operand> __VCMUL <vector operand> | <vector operand> __VCMUL <scalar operand>;
Beispiel für eine Multiplikationsoperation:
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;
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 für eine Divisionsoperation:
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;
Der Operator berechnet das Punktprodukt (Skalarprodukt) zweier Vektoren.
Syntax:
<scalar variable> := <1st vector operand> __VCDOT <2nd vector operand>;
Beispiel für ein 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
Der Operator berechnet die Quadratwurzel jedes Elements im Vektor.
Syntax:
<vector variable> := __VCSQRT <vector operand>;
Beispiel für eine 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);
Der Operator berechnet den maximalen Vektor zweier Vektoren. Das Maximum wird Element für Element ermittelt.
Syntax:
<vector variable> := __VCMAX <1st vector operand>, <2nd vector operand>;
Beispiel für einen maximalen Vektor:
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);
Der Operator berechnet den minimalen Vektor zweier Vektoren. Das Minimum wird Element für Element ermittelt.
Syntax:
<vector variable> := __VCMIN <1st vector operand>, <2nd vector operand>;
Beispiel für einen minimalen Vektor:
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);
Der Operator setzt die Elemente eines Vektors in einer Anweisung. Die Elemente sind vom 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);
Der Operator setzt die Elemente eines Vektors in einer Anweisung. Die Elemente sind vom Datentyp LREAL.
Sie können den Operator verwenden, wenn die Variablen gültig sind, z. B. in Anweisungen, 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);
Der Operator interpretiert jeden willkürlichen Speicherbereich als Vektor. Das kann sich für die Verbindung von Vektorvariablen mit bestehendem Code als nützlich erweisen.
Für den Operator sind zwei Parameter erforderlich:
Der erste Parameter gibt die Anzahl der Vektorelemente an.
Der zweite Parameter ist ein Zeiger auf die REAL-Daten.
__VCLOAD_REAL (<n>,<ptr>) liest <n> aufeinander folgende REAL-Werte an der Adresse <ptr>. Stellen Sie sicher, dass <n> Werte an dieser Adresse vorhanden sind.
VORSICHT | |
---|---|
Syntax:
<vector variable> __VCLOAD_REAL( <vector size>, ( < pointer to data of type REAL> ) ;
<vector size> : 2 | 3 | 4 | 5| 6 | 7| 8
Beispiel für eine Interpretation als Vektor:
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]));
Der Operator interpretiert jeden willkürlichen Speicherbereich als Vektor. Das kann sich für die Verbindung von Vektorvariablen mit bestehendem Code als nützlich erweisen.
Für den Operator sind zwei Parameter erforderlich:
Der erste Parameter gibt die Anzahl der Vektorelemente an.
Der zweite Parameter ist ein Zeiger auf die LREAL-Daten.
__VCLOAD_LREAL (<n>,<ptr>) liest <n> aufeinander folgende LREAL-Werte an der Adresse <ptr>. Stellen Sie sicher, dass <n> Werte an dieser Adresse vorhanden sind.
VORSICHT | |
---|---|
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
Beispiel für eine Interpretation als Vektor:
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]));
Der Operator speichert/kopiert den Inhalt des Vektors an der angegebenen Speicheradresse. Es werden die Nummer und der Typ der Elemente aus den Vektorvariablen angewendet.
__VCSTORE(<n>,<ptr>) schreibt <n> aufeinander folgende Werte an der Adresse <ptr>. Stellen Sie sicher, dass <n> Werte an dieser Adresse vorhanden sind.
VORSICHT | |
---|---|
Syntax:
__VCSTORE( <pointer to data>, <vector variable> );
Beispiel für eine Speicherung:
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);