使用向量库

如果要 显式 调用任何 MASS 向量函数,那么可以通过在源文件中包含 massv.h 并将应用程序与相应的向量库链接来执行此操作。 使用 MASS 编译和链接程序中提供了有关链接的信息。

下面列出了 XL C/C++ 随附的向量库:
libmassv.a
在任何 支持的 POWER ® 处理器上运行的通用向量库。 除非应用程序需要此可移植性,否则请使用以下相应特定于体系结构的库以获得最大性能。
libmassvp4.a
包含针对 POWER4 体系结构调整的一些功能。 其余函数与 libmassv.a 中的函数相同。 如果您正在使用 PPC970 机器,那么建议选择此库。
libmassvp5.a
包含针对 POWER5 体系结构调整的一些功能。 其余函数与 libmassv.a 中的函数相同。
libmassvp6.a
包含一些针对 POWER6 架构调整的功能。 其余函数与 libmassv.a 中的函数相同。
libmassvp7.a
包含为 POWER7 架构调整的功能。
libmassvp8.a
包含为 POWER8 架构调整的功能。
libmassvp9.a
包含为 POWER9 架构调整的功能。

所有库都可以在 32 位或 64 位方式下使用。

向量库中包含的单精度和双精度浮点函数在 表 1中进行了汇总。 向量库中包含的整数函数在 表 2中进行了汇总。 请注意,在 C 和 C++ 应用程序中,仅支持通过引用调用,即使是对于标量自变量也是如此。

除少数函数 (在以下段落中描述) 外,向量库中的所有浮点函数都接受三个 参数:
  • 双精度 (对于双精度函数) 或单精度 (对于单精度函数) 向量输出 参数
  • 双精度 (对于双精度函数) 或单精度 (对于单精度函数) 向量输入 参数
  • 整数向量长度 参数。
函数的格式
function_name (y,x,n)
其中 y 是目标向量,X 是源向量,n 是向量长度。 假定 参数 yx 对于前缀为 v的函数为双精度,对于前缀为 vs的函数为单精度。 作为示例,以下代码输出长度为 500 的向量 y ,其元素为 exp (x [i]) ,其中 i=0 , ... , 499:
#include <massv.h>

double x[500], y[500];
int n;
n = 500;
...
vexp (y, x, &n);

函数 vdivvsincosvpowvatan2(及其单精度版本 vsdivvssincosvspowvsatan2)采用四个自变量。 函数 vdivvpowvatan2 采用自变量 (zxyn)。 函数 vdiv 输出一个向量 z ,其元素为 x [i] /y [i] ,其中 i=0,..,*n–1。 函数 vpow 输出其元素为 x [i]y [i],其中 i=0,..,*n–1的向量 。 函数 vatan2 输出一个向量 z ,其元素为 atan (x [i] /y [i]) ,其中 i=0,..,*n–1。 函数 vsincos 采用自变量 (yzxn) ,并输出两个向量 yz,其元素分别为 sin (x [i])cos (x [i])

vcosisin(y,x,n)vscosisin(y,x,n)中, xn 个元素的向量,函数输出 n __Complex 个格式为 (cos (x [i]) , sin (x [i]))的元素的向量 y如果使用 -D__nocomplex (请参阅 表 1中的注释) ,那么输出向量包含 y [0] [i] = cos (x [i]) 和 y [1] [i] = sin (x [i]) ,其中 i=0,..,*n-1。

表 1. MASS 浮点向量函数
双精度函数 单精度函数 描述 双精度函数原型 单精度函数原型
vacos vsacos y[i] 设置为 x[i]的反余弦值,对于 i=0,..,*n-1 void vacos (double y[], double x[], int *n); void vsacos (float y[], float x[], int *n);
vacosh vsacosh y[i] 设置为 x[i]双曲弧余弦 ,对于 i=0,..,*n-1 void vacosh (double y[], double x[], int *n); void vsacosh (float y[], float x[], int *n);
vasin vsasin y[i] 设置为 x[i] 的反正弦值,i=0,..,*n-1) void vasin (double y[], double x[], int *n); void vsasin (float y[], float x[], int *n);
vasinh vsasinh y[i] 设置为 x[i] 的反双曲正弦,i=0,..,*n-1 void vasinh (double y[], double x[], int *n); void vsasinh (float y[], float x[], int *n);
vatan2 vsatan2 z[i] 设置为 x[i]/y[i] 的反正切值,i=0,..,*n-1 void vatan2 (double z[], double x[], double y[], int *n); void vsatan2 (float z[], float x[], float y[], int *n);
vatanh vsatanh y[i] 设置为 x[i] 的双曲反正切值,i=0,..,*n-1 void vatanh (double y[], double x[], int *n); void vsatanh (float y[], float x[], int *n);
vcbrt vscbrt y[i] 设置为 x[i] 的立方根,i=0,..,*n-1 void vcbrt (double y[], double x[], int *n); void vscbrt (float y[], float x[], int *n);
vcos vscos y[i] 设置为 x[i] 的余弦值,i=0,..,*n-1 void vcos (double y[], double x[], int *n); void vscos (float y[], float x[], int *n);
vcosh vscosh y[i] 设置为 x[i] 的双曲余弦,i=0,..,*n-1 void vcosh (double y[], double x[], int *n); void vscosh (float y[], float x[], int *n);
Vcosisin1 vscosisin1 y[i] 的实数部分设置为 x[i] 的余弦值,将 y[i] 的非实数部分设置为 x[i] 的正弦值,i=0,..,*n-1 void vcosisin (double _Complex y[], double x[], int *n); void vscosisin (float _Complex y[], float x[], int *n);
vdint   y[i] 设置为 x[i] 的整数截断,i=0,..,*n-1 void vdint (double y[], double x[], int *n);  
vdiv vsdiv z[i] 设置为 x[i]/y[i],i=0,..,*n–1 void vdiv (double z[], double x[], double y[], int *n); void vsdiv (float z[], float x[], float y[], int *n);
vdnint   y[i] 设置为 x[i] 的最接近的整数,i=0,..,*n-1 void vdnint (double y[], double x[], int *n);  
verf vserf y[i] 设置为 x[i] 的误差函数,i=0,..,*n-1 void verf (double y[], double x[], int *n) void vserf (float y[], float x[], int *n)
verfc vserfc y[i] 设置为 x[i] 的互补误差函数,i=0,..,*n-1 void verfc (double y[], double x[], int *n) void vserfc (float y[], float x[], int *n)
vexp vsexp y[i] 设置为 x[i] 的指数函数,i=0,..,*n-1 void vexp (double y[], double x[], int *n); void vsexp (float y[], float x[], int *n);
vexp2 vsexp2 y[i] 设置为 2 的 x[i] 次幂,i=1,..,*n-1 void vexp2 (double y[], double x[], int *n); void vsexp2 (float y[], float x[], int *n);
vexpm1 vsexpm1 y[i] 设置为 (x[i] 的指数函数)-1,i=0,..,*n-1 void vexpm1 (double y[], double x[], int *n); void vsexpm1 (float y[], float x[], int *n);
vexp2m1 vsexp2m1 y[i] 设置为 (2 的 x[i] 次幂) - 1,i=1,..,*n-1 void vexp2m1 (double y[], double x[], int *n); void vsexp2m1 (float y[], float x[], int *n);
vhypot vshypot z[i] 设置为 x[i]y[i] 的平方和的平方根,i=0,..,*n-1 void vhypot (double z[], double x[], double y[], int *n); void vshypot (float z[], float x[], float y[], int *n);
vlog vslog y[i] 设置为 x[i] 的自然对数,i=0,..,*n-1 void vlog (double y[], double x[], int *n); void vslog (float y[], float x[], int *n);
vlog2 vslog2 y[i] 设置为 x[i] 的以 2 为基数的对数,i=1,..,*n-1 void vlog2 (double y[], double x[], int *n); void vslog2 (float y[], float x[], int *n);
vlog10 vslog10 y[i] 设置为 x[i] 的以 10 为基数的对数,i=0,..,*n-1 void vlog10 (double y[], double x[], int *n); void vslog10 (float y[], float x[], int *n);
vlog1p vslog1p y[i] 设置为 (x[i]+1) 的自然对数,i=0,..,*n-1 void vlog1p (double y[], double x[], int *n); void vslog1p (float y[], float x[], int *n);
vlog21p vslog21p y[i] 设置为 (x[i]+1) 的以 2 为基数的对数,i=1,..,*n-1 void vlog21p (double y[], double x[], int *n); void vslog21p (float y[], float x[], int *n);
vpow vspow z[i] 设置为 x[i]y[i] 次幂,i=0,..,*n-1 void vpow (double z[], double x[], double y[], int *n); void vspow (float z[], float x[], float y[], int *n);
vqdrt vsqdrt y[i] 设置为 x[i] 的四次方根,i=0,..,*n-1 void vqdrt (double y[], double x[], int *n); void vsqdrt (float y[], float x[], int *n);
vrcbrt vsrcbrt y[i] 设置为 x[i] 的四次方根的倒数,i=0,..,*n-1 void vrcbrt (double y[], double x[], int *n); void vsrcbrt (float y[], float x[], int *n);
vrec vsrec y[i] 设置为 x[i] 的倒数,i=0,..,*n-1 void vrec (double y[], double x[], int *n); void vsrec (float y[], float x[], int *n);
vrqdrt vsrqdrt y[i] 设置为 x[i] 的四次方根的倒数,i=0,..,*n-1 void vrqdrt (double y[], double x[], int *n); void vsrqdrt (float y[], float x[], int *n);
vrsqrt vsrsqrt y[i] 设置为 x[i] 的平方根的倒数,i=0,..,*n-1 void vrsqrt (double y[], double x[], int *n); void vsrsqrt (float y[], float x[], int *n);
vsin vssin y[i] 设置为 x[i] 的正弦值,i=0,..,*n-1 void vsin (double y[], double x[], int *n); void vssin (float y[], float x[], int *n);
vsincos vssincos y[i] 设置为 x[i] 的正弦值,将 z[i] 设置为 x[i] 的余弦值,i=0,..,*n-1 void vsincos (double y[], double z[], double x[], int *n); void vssincos (float y[], float z[], float x[], int *n);
vsinh vssinh y[i] 设置为 x[i] 的双曲正弦值,i=0,..,*n-1 void vsinh (double y[], double x[], int *n); void vssinh (float y[], float x[], int *n);
vsqrt vssqrt y[i] 设置为 x[i] 的平方根,i=0,..,*n-1 void vsqrt (double y[], double x[], int *n); void vssqrt (float y[], float x[], int *n);
vtan vstan y[i] 设置为 x[i] 的正切值,i=0,..,*n-1 void vtan (double y[], double x[], int *n); void vstan (float y[], float x[], int *n);
vtanh vstanh y[i] 设置为 x[i] 的双曲正切值,for i=0,..,*n-1 void vtanh (double y[], double x[], int *n); void vstanh (float y[], float x[], int *n);
注意:
  1. 缺省情况下,这些函数使用 __Complex 数据类型,此数据类型仅适用于 AIX® 5.2 及更高版本,并且不会在较低版本的操作系统上进行编译。 要获取这些函数的替代原型,请使用 -D__nocomplex 进行编译。 这将函数定义为 void vcosisin (double y[][2], double *x, int *n);void vscosisin(float y[][2], float *x, int *n);

整数函数的格式为 function_name (x[], *n),其中,x[] 是 4 字节向量(针对 vpopcnt4)或 8 字节(针对 vpopcnt8)数字对象(整型或浮点),*n 是向量长度。

表 2。 MASS 整数向量库函数
函数 描述 原型
vpopcnt4 返回 x[i] (i=0,..,*n–1) 的二进制表示的并置中的 1 位总数,其中 x 是 32 位对象的向量。 unsigned int vpopcnt4 (void *x, int *n)
vpopcnt8 返回 x[i] (i=0,..,*n–1) 的二进制表示的并置中 1 位的总数,其中 x是 64 位对象的向量 unsigned int vpopcnt8 (void *x, int *n)

输入和输出向量的重叠

在大多数应用程序中,MASS 向量函数是用不相交的输入和输出向量调用的;也就是说,两个向量在内存中不重叠。 另一个常见的用法方案是使用相同的向量对输入和输出参数 (例如, vsin (y, y, &n)) 进行调用。 对于其他类型的重叠,请确保遵守以下限制,以确保应用程序的正确操作:
  • 对于使用一个输入和一个输出向量的向量函数的调用(例如, vsin (y, x, &n)):

    向量 x[0:n-1]y[0:n-1] 必须不相关或完全相同,或者 x[0] 的地址必须大于 y[0]的地址。 即,如果 xy 不是同一向量,那么 y[0] 的地址不得在 x[0:n-1]覆盖的地址范围内,否则可能会获得意外结果。

  • 对于使用两个输入向量的向量函数的调用(例如,vatan2 (y, x1, x2, &n)):

    上述限制适用于 y,x1y,x2 这两个向量对。 即,如果 yx1不是同一向量,那么 y[0] 的地址不得在 x1[0:n-1]所覆盖的地址范围内; 如果 yx2不是同一向量,那么 y[0] 的地址不得在 x2[0:n-1]所覆盖的地址范围内。

  • 对于使用两个输出向量的向量函数的调用(例如,vsincos (x, y1, y2, &n)):

    先前限制同时适用于 y1,xy2,x 向量对。 即,如果 y1x 不是同一向量,那么 y1[0] 的地址不得在 x[0:n-1]覆盖的地址范围内; 如果 y2x 不是同一向量,那么 y2[0] 的地址不得在 x[0:n-1]覆盖的地址范围内。 此外,向量 y1[0:n-1]y2[0:n-1] 必须不相关。

输入向量和输出向量的对齐

要从 POWER7 和 POWER8 向量库获取最佳性能,请在 8 字节 (或更好, 16 字节) 边界上对齐输入和输出向量。

MASS 向量函数的一致性

向量函数的精度与 libmass.a 中相应标量函数的精度相当,但结果可能不相同。

为了提高速度,MASS 库做出了一定的权衡取舍。 其中一个权衡涉及到某些 MASS 向量函数的一致性。 对于某些函数,根据特定输入值在向量中的位置、向量长度和输入向量的附近元素,为特定输入值计算的结果可能会略有不同(通常仅在最低有效位)。 此外,不同 MASS 库产生的结果不一定按位相同。

libmassvp7.alibmassvp8.a 中的所有函数都是一致的。

以下函数在它们出现的所有版本的库中都是一致的。
双精度函数
vacos, vacosh, vasin, vasinh, vatan2, vatanh, vcbrt, vcos, vcosh, vcosisin, vdint, vdnint, vexp2, vexpm1, vexp2m1, vlog, vlog2, vlog10, vlog1p, vlog21p, vpow, vqdrt, vrcbrt, vrqdrt, vsin, vsincos, vsinh, vtan, vtanh
单精度函数
vsacos, vsacosh, vsasin, vsasinh, vsatan2, vsatanh, vscbrt, vscos, vscosh, vscosisin, vsexp, vsexp2, vsexpm1, vsexp2m1, vslog, vslog2, vslog10, vslog1p, vslog21p, vspow, vsqdrt, vsrcbrt, vsrqdrt, vssin, vssincos, vssinh, vssqrt, vstan, vstanh

以下函数在 libmassvp3.alibmassvp4.alibmassvp5.alibmassvp6.a中一致:

vsqrtvrsqrt.

以下函数在 libmassvp4.alibmassvp5.alibmassvp6.a 中一致:

vrec、、vsrecvdivvsdivvexp

以下函数在 libmassv.alibmassvp5.alibmassvp6.a 中一致:

vsrsqrt.

Mathematical Acceleration Subsystem for AIX Web 站点上提供了这些功能中某些功能的较旧的不一致版本。 如果不需要一致性,那么使用旧版本可能具有性能优势。 有关一致性和避免与向量库不一致的更多信息,以及性能和准确性数据,请参阅 Mathematical Acceleration Subsystem Web 站点