Skip to main content

数据类型:__VECTOR

注意

向量运算仅在 64 位处理器上受本机支持,并且仅在这些处理器上提供性能优势。控制器的数据表提供了有关控制器上使用的处理器的信息。

目前,原生支持带有 SSE2 的 x86/64 位平台和带有 NEON 的 ARM64 上的向量操作。在所有其他平台上,向量操作都被转换为单独的语句。例如,向量加法然后通过多个单一的加法运算来执行。

处理器的命令集扩展是 SIMD 扩展。 SIMD(单指令多数据)描述了一种计算机体系结构,其中相同类型的多个数据集同时并行处理,因此通过一个命令调用速度更快。例如,在向量运算中,可以同时添加 4 对数字。

句法

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

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

变量的初始化是可选的。

矢量数据类型是一个浮点数数组,最多包含 8 个元素。这 __vc<operator name> 运算符可用于此数据类型。您可以使用它们来实现向量操作,而无需额外的函数调用。

索引访问的语法

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

索引向量变量时,您可以访问向量的单个元素。索引从 0 开始,一直到 <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;

确定最佳向量大小

提示

使用取决于您的目标系统的最佳向量大小作为向量大小,以便编写最有效的代码。

对于计算机架构通常适合向量处理的目标系统,我们不建议使用任意大小的向量。根据处理器的数据处理类型,存在一个最佳向量大小。使用此数组大小声明的向量将被尽快处理。声明为更大数组的向量在速度上没有优势。声明为较小数组的向量没有充分利用处理器的能力。

您可以在运行时查询最佳大小。您可以在常量中找到信息 Constants.vcOptimalREAL (对于带有 REAL 元素)和 Constants.vcOptimalLREAL (对于带有 LREAL 元素)。常数有 LREAL 数据类型。如果常量返回值 1 作为最优值,这意味着加速矢量处理不适用于目标系统。

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;

加载在 CODESYS Control Win V3 x64 目标系统在运行时返回以下值:

_cds_img_read_optimal_vector_size.png

运算符:__VCADD

运算符计算两个向量的和。

句法

<vector variable> := <1st vector operand> __VCADD <2nd vector operand>;
241. 添加
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;


运算符:__VCSUB

运算符计算两个向量之间的差异。

句法

<vector variable> := <vector minuend> __VCSUB <vector subtrahend>;
242. 减法
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;


运算符:__VCMUL

运算符计算两个向量或一个标量(浮点数)和一个向量的乘积。

句法

<vector variable> := <1st vector operand> __VCMUL <2nd vector operand> | <scalar operand> __VCMUL <vector operand> | <vector operand> __VCMUL <scalar operand> ;
243. 乘法
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;


运算符:__VCDIV

运算符计算两个向量或一个向量和一个标量的商。

句法

<vector variable> := <vector dividend> __VCDIV <vector divisor> | < vector dividend> __VCMUL <scalar divisor> ;
244. 分配
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;


运算符:__VCDOT

运算符计算两个向量的点积(标量积)。

句法

<skalar variable> := <1st vector operand> __VCDOT <2nd vector operand> ;
245. 点积
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


运算符:__VCSQRT

运算符计算向量中每个元素的平方根。

句法

<vector variable> := __VCSQRT( <vector operand> );
246. 平方根
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);


运算符:__VCMAX

运算符计算两个向量的最大向量。最大值是逐个元素确定的。

句法

<vector variable> := __VCMAX( <1st vector operand>, <2nd vector operand>);
247. 最大向量
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);


运算符:__VCMIN

运算符计算两个向量的最小向量。最小值是逐个元素确定的。

句法

<vector variable> := __VCMIN( <1st vector operand>, <2nd vector operand>);
248. 最小向量示例
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);


运算符:__VCSET_REAL

运算符在语句中设置向量的所有元素。元素有 REAL 数据类型。

句法

<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);

运算符:__VCSET_LREAL

运算符在语句中一次设置向量的所有元素。元素有 LREAL 数据类型。

它们可以在变量有效的地方使用,例如实现中的赋值或函数调用中的参数。

句法

<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);

运算符:__VCLOAD_REAL

运算符将任意内存区域解释为向量。这有助于将向量变量连接到现有代码。运算符需要 2 个参数。第一个参数表示向量元素的数量。第二个参数是指向 REAL 数据。

重要

__VCLOAD_REAL(<n>,<ptr>)<n> 连续的 REAL 值 <ptr> 地址。如果少于 <n> 值,那么这可能导致控制器崩溃或读取不需要的内存。

句法

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


运算符:__VCLOAD_LREAL

运算符将任意内存区域解释为向量。这有助于将向量变量连接到现有代码。运算符需要 2 个参数。第一个参数表示向量元素的数量。第二个参数是指向 LREAL 数据。

重要

__VCLOAD_LREAL (<n>,<ptr>)<n> 在连续的 LREAL 值 <ptr> 地址。如果少于 <n> 值,那么这可能导致控制器崩溃或读取不需要的内存。

句法

<vector variable> := __VCLOAD_LREAL( <vector size>, <pointer to data of type LREAL> );
<number of vector elements> : 1 | 2 | 3 | 4 | 5| 6 | 7| 8
250. 矢量化
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]));


运营商:__VCSTORE

运算符将向量的内容保存/复制到指定的内存地址。元素的数量和类型从向量变量中自动应用。

重要

__VCSTORE(<n>,<ptr>)<n> 在连续值 <ptr> 地址。如果少于 <n> 此地址的值,则这可能导致控制器崩溃或写入不需要的内存。

句法

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