使用向量库
如果要 显式 调用任何 MASS 向量函数,那么可以通过在源文件中包含 massv.h 并将应用程序与相应的向量库链接来执行此操作。 使用 MASS 编译和链接程序中提供了有关链接的信息。
- 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 是向量长度。 假定 参数 y 和 x 对于前缀为 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);
函数 vdiv、vsincos、vpow 和 vatan2(及其单精度版本 vsdiv、vssincos、vspow 和 vsatan2)采用四个自变量。 函数 vdiv, vpow和 vatan2 采用自变量 (z,x,y,n)。 函数 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 采用自变量 (y,z,x,n) ,并输出两个向量 y 和 z,其元素分别为 sin (x [i]) 和 cos (x [i])。
在 vcosisin(y,x,n) 和 vscosisin(y,x,n)中, x 是 n 个元素的向量,函数输出 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。
| 双精度函数 | 单精度函数 | 描述 | 双精度函数原型 | 单精度函数原型 |
|---|---|---|---|---|
| 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); |
注意:
|
||||
整数函数的格式为 function_name (x[], *n),其中,x[] 是 4 字节向量(针对 vpopcnt4)或 8 字节(针对 vpopcnt8)数字对象(整型或浮点),*n 是向量长度。
| 函数 | 描述 | 原型 |
|---|---|---|
| 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) |
输入和输出向量的重叠
vsin (y, y, &n)) 进行调用。 对于其他类型的重叠,请确保遵守以下限制,以确保应用程序的正确操作:- 对于使用一个输入和一个输出向量的向量函数的调用(例如,
vsin (y, x, &n)):向量
x[0:n-1]和y[0:n-1]必须不相关或完全相同,或者x[0]的地址必须大于y[0]的地址。 即,如果x和y不是同一向量,那么y[0]的地址不得在x[0:n-1]覆盖的地址范围内,否则可能会获得意外结果。 - 对于使用两个输入向量的向量函数的调用(例如,
vatan2 (y, x1, x2, &n)):上述限制适用于
y,x1和y,x2这两个向量对。 即,如果y与x1不是同一向量,那么y[0]的地址不得在x1[0:n-1]所覆盖的地址范围内; 如果y与x2不是同一向量,那么y[0]的地址不得在x2[0:n-1]所覆盖的地址范围内。 - 对于使用两个输出向量的向量函数的调用(例如,
vsincos (x, y1, y2, &n)):先前限制同时适用于
y1,x和y2,x向量对。 即,如果y1和x不是同一向量,那么y1[0]的地址不得在x[0:n-1]覆盖的地址范围内; 如果y2和x不是同一向量,那么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.a 和 libmassvp8.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.a, libmassvp4.a, libmassvp5.a和 libmassvp6.a中一致:
vsqrt 和 vrsqrt.
以下函数在 libmassvp4.a、libmassvp5.a 和 libmassvp6.a 中一致:
vrec、、vsrec、vdiv、vsdiv 和 vexp。
以下函数在 libmassv.a、libmassvp5.a 和 libmassvp6.a 中一致:
vsrsqrt.
Mathematical Acceleration Subsystem for AIX Web 站点上提供了这些功能中某些功能的较旧的不一致版本。 如果不需要一致性,那么使用旧版本可能具有性能优势。 有关一致性和避免与向量库不一致的更多信息,以及性能和准确性数据,请参阅 Mathematical Acceleration Subsystem Web 站点。