'vector long long' 的可用性如何?

What is the availability of 'vector long long'?

我正在旧的 PowerMac G5 上进行测试,它是一台 Power4 计算机。构建失败:

$ make
...
g++ -DNDEBUG -g2 -O3 -mcpu=power4 -maltivec -c ppc-simd.cpp
ppc-crypto.h:36: error: use of 'long long' in AltiVec types is invalid
make: *** [ppc-simd.o] Error 1

失败的原因是:

typedef __vector unsigned long long uint64x2_p8;

我无法确定何时应该提供 typedef。 -mcpu=power4 -maltivec 机器报告 64 位可用性:

$ gcc -mcpu=power4 -maltivec -dM -E - </dev/null | sort | egrep -i -E 'power|ARCH'
#define _ARCH_PPC 1
#define _ARCH_PPC64 1
#define __POWERPC__ 1

OpenPOWER | 6.1. Vector Data Types 手册中有关于矢量数据类型的很好的信息,但没有讨论 vector long long 何时可用。

__vector unsigned long long 的可用性如何?我什么时候可以使用 typedef?

TL:DR:看起来 POWER7 是 AltiVec 对 64 位元素大小的最低要求。这是 VSX (Vector Scalar Extension) 的一部分,维基百科证实它首次出现在 POWER7 中。


gcc 很可能知道它在做什么,并以最低的 -mcpu= 要求启用 64 位元素大小向量内在函数。

#include <altivec.h>

auto vec32(void) {       // compiles with your options: Power4
    return vec_splats((int) 1);
}

// gcc error: use of 'long long' in AltiVec types is invalid without -mvsx
vector long long vec64(void) {
    return vec_splats((long long) 1);
}

(使用 auto 而不是 vector long long,第二个函数编译为返回两个 64 位整数寄存器。)

添加 -mvsx 让第二个函数编译。使用 -mcpu=power7 也可以,但 power6 不行。

source + asm on Godbolt (PowerPC64 gcc6.3)

# with auto without VSX:
vec64():     # -O3 -mcpu=power4 -maltivec -mregnames
    li %r4,1
    li %r3,1
    blr

vec64():  # -O3 -mcpu=power7 -maltivec -mregnames
.LCF2:
0:  addis 2,12,.TOC.-.LCF2@ha
    addi 2,2,.TOC.-.LCF2@l
    addis %r9,%r2,.LC0@toc@ha
    addi %r9,%r9,.LC0@toc@l       # PC-relative addressing for static constant, I think.
    lxvd2x %vs34,0,%r9            # vector load?
    xxpermdi %vs34,%vs34,%vs34,2
    blr


 .LC0:    # in .rodata
    .quad   1
    .quad   1

顺便说一句,vec_splats(splat 标量)带有一个常量编译成一条指令。但是使用运行时变量(例如函数 arg),它会编译为整数存储/矢量加载/矢量 splat(如 vec_splat 内在函数)。显然没有一条指令用于 int->vec.

vec_splat_s32 和相关内在函数 接受一个小的(5 位)常量,因此它们仅在编译器可以使用相应的 splat- 的情况下编译即时指令。

这个 Intel SSE to PowerPC AltiVec migration 看起来大部分都不错,但是弄错了(它声称 vec_splats splats a signed byte)。