矢量运算仅在 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 // (...)? : Optional
向量数据类型是最多包含 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 elements iOVS_LREAL : INT; // Optimal vector size for LREAL elements END_VAR iOVS_REAL := Constants.vcOptimalREAL; iOVS_LREAL := Constants.vcOptimalLREAL;
在CODESYS Control Win V3 x64 目标机系统上加载的应用程序在运行时会返回以下值:

Operator __VCADD
运算符计算两个向量的和。
语法
<vector variable> := <1st vector operand> __VCADD <2nd vector operand>;
加法举例
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
运算符计算两个向量之间的差值。
语法
<vector variable> := <vector minuend> __VCSUB <vector subtrahend>;
减法示例
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> ;
乘法举例
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> ;
除法举例
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;
运营商
该运算符计算两个向量的点积(标量积)。
语法
<scalar variable> := <1st vector operand> __VCDOT <2nd vector operand> ;
点积示例
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
运算符计算向量中每个元素的平方根。
语法
<vector variable> := __VCSQRT( <vector operand> );
平方根示例
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
运算符计算两个向量的最大值。最大值是逐个元素确定的。
语法
<vector variable> := __VCMAX( <1st vector operand>, <2nd vector operand>);
最大矢量示例
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>);
最小矢量示例
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
该运算符在语句中设置一个向量的所有元素。元素的数据类型为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);
Operator __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);
Operator __VCLOAD_REAL
运算符可将任意内存区域解释为矢量。这有助于将矢量变量与现有代码连接起来。操作符需要 2 个参数。第一个参数表示向量元素的数量。第二个参数是指向REAL
数据的指针。
语法
<vector variable> := __VCLOAD_REAL( <vector size>, <pointer to data of type REAL> ) ; <vector size> : 2 | 3 | 4 | 5| 6 | 7| 8
矢量化示例
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
运算符可将任意内存区域解释为矢量。这有助于将矢量变量与现有代码连接起来。操作符需要 2 个参数。第一个参数表示向量元素的数量。第二个参数是指向LREAL
数据的指针。
语法
<vector variable> := __VCLOAD_REAL( <vector size>, <pointer to data of type LREAL> ); <number of vector elements> : 1 | 2 | 3 | 4 | 5| 6 | 7| 8
矢量化示例
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);
操作符__VCSTORE
操作符将向量内容保存/复制到指定的内存地址。矢量变量会自动应用元素的数量和类型。
语法
__VCSTORE( <pointer to data>, <vector variable> );
存储示例
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);