Art*_*yom 3 c++ gcc simd clang
我需要使用GCC向量扩展来访问未对齐的值
下面的程序崩溃了 - 包括clang和gcc
typedef int __attribute__((vector_size(16))) int4;
typedef int __attribute__((vector_size(16),aligned(4))) *int4p;
int main()
{
int v[64] __attribute__((aligned(16))) = {};
int4p ptr = reinterpret_cast<int4p>(&v[7]);
int4 val = *ptr;
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我改变
typedef int __attribute__((vector_size(16),aligned(4))) *int4p;
Run Code Online (Sandbox Code Playgroud)
至
typedef int __attribute__((vector_size(16),aligned(4))) int4u;
typedef int4u *int4up;
Run Code Online (Sandbox Code Playgroud)
生成的汇编代码是正确的(使用未对齐的加载) - 在clang和gcc中.
单一定义有什么问题或者我错过了什么?clang和gcc都可以是同一个bug吗?
注意:它发生在clang和gcc中
您已经改变了指针类型本身的对齐方式,而不是指针类型.这与vector_size属性以及与属性有关的所有内容无关aligned.它也不是一个bug,它在GCC和Clang中都能正确实现.
从GCC文档中,§6.33.1公共类型属性 (重点添加):
aligned(对齐)此属性指定指定类型的变量的最小对齐(以字节为单位).[...]
有问题的类型是声明的类型,而不是 被声明的类型指向的类型.因此,
typedef int __attribute__((vector_size(16),aligned(4))) *int4p;
Run Code Online (Sandbox Code Playgroud)
声明一个新类型T,指向*T类型的对象,其中:
同时,§6.49通过内置函数使用向量指令说(强调添加):
在某些目标上,指令集包含SIMD向量指令,这些指令同时对一个大寄存器中包含的多个值进行操作.例如,在x86上MMX,3DNow!和SSE扩展可以这种方式使用.
使用这些扩展的第一步是提供必要的数据类型.这应该使用适当的
typedef:Run Code Online (Sandbox Code Playgroud)typedef int v4si __attribute__ ((vector_size (16)));的
int类型指定的基本类型,而属性指定为变量的矢量的大小,以字节为单位.例如,上面的声明使编译器将v4si类型的模式设置为16字节宽,并分为int大小的单位.对于32位int,这意味着4个4字节单位的向量,foo的对应模式是V4SI.该
vector_size属性仅适用于整数和浮点标量,但允许数组,指针和函数返回值与此结构一起使用.目前只允许功率为2的大小.
#include <stdio.h>
typedef int __attribute__((aligned(128))) * batcrazyptr;
struct batcrazystruct{
batcrazyptr ptr;
};
int main()
{
printf("Ptr: %zu\n", sizeof(batcrazyptr));
printf("Struct: %zu\n", sizeof(batcrazystruct));
}
Run Code Online (Sandbox Code Playgroud)
输出:
Ptr: 8
Struct: 128
Run Code Online (Sandbox Code Playgroud)
这与其batcrazyptr ptr 自身的一致性有所改变,而不是它的指针,并与文档一致.
我怕你会被迫使用链typedef的,因为你有做int4u.有一个单独的属性来指定a中每个指针级别的对齐是不合理的typedef.