Skip to main content

Datentyp: __VECTOR

Anmerkung

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

Die Initialisierung der Variablen ist 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.

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

Tipp

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.

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:

_cds_img_read_optimal_vector_size.png

Operator: __VCADD

Der Operator berechnet die Summe zweier Vektoren.

Syntax

<vector variable> := <1st vector operand> __VCADD <2nd vector operand>;
Beispiel 241. 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 242. 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 243. 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 244. 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 245. 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 246. 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 247. 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 248. 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
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
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.

Wichtig

__VCLOAD_REAL(<n>,<ptr>) liest <n> aufeinander folgende REAL-Werte an der Adresse <ptr>. Wenn sich weniger als <n> Werte an dieser Adresse befinden, kann dies zum Absturz der Steuerung führen oder unerwünschten Speicher lesen.

Syntax

<vector variable> := __VCLOAD_REAL( <vector size>, <pointer to data of type REAL> ) ;
<vector size> : 2 | 3 | 4 | 5| 6 | 7| 8
Beispiel 249. Vektorisieren
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

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.

Wichtig

__VCLOAD_LREAL (<n>,<ptr>) liest <n> aufeinander folgende LREAL-Werte an der Adresse <ptr>. Wenn sich weniger als <n> Werte an dieser Adresse befinden, kann dies zum Absturz der Steuerung führen oder unerwünschten Speicher lesen.

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 250. Vektorisieren
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

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.

Wichtig

__VCSTORE(<n>,<ptr>) schreibt <n> aufeinander folgende Werte an der Adresse <ptr>. Wenn sich weniger als <n> Werte an dieser Adresse befinden, kann dies zum Absturz der Steuerung führen oder unerwünschten Speicher schreiben.

Syntax

__VCSTORE( <pointer to data>, <vector variable> );
Beispiel 251. Speichern
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);