我需要使用GCC向量扩展
来访问未对齐的值下面的程序崩溃了 - 在clang和gcc
中CREATE TABLE `a` (
`ID` int(11) NOT NULL,
`date` datetime DEFAULT,
PRIMARY KEY (`ID`),
KEY `date` (`date`),
)
CREATE TABLE `b` (
`bID` int(11) NOT NULL,
`ID` int(11) NOT NULL,
`cID` int(11) DEFAULT,
PRIMARY KEY (`bID`),
KEY `cID` (`cID`),
)
但是,如果我改变
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;
}
到
typedef int __attribute__((vector_size(16),aligned(4))) *int4p;
生成的汇编代码是正确的(使用未对齐的加载) - 在clang和gcc中。
单一定义有什么问题或者我错过了什么?在clang和gcc中它可以是同一个bug吗?
注意:它在clang和gcc中都会发生
答案 0 :(得分:6)
您已经更改了指针类型本身的对齐方式,而不是指针类型。这与vector_size
属性以及与aligned
属性有关的所有内容无关。它也不是一个bug,它在GCC和Clang中都得到了正确的实现。
在GCC文档中,§ 6.33.1 Common Type Attributes (重点已添加):
aligned
(路线)此属性指定指定类型的变量的最小对齐(以字节为单位)。 [...]
有问题的类型是被声明的类型,不是 被声明的类型所指向的类型。因此,
typedef int __attribute__((vector_size(16),aligned(4))) *int4p;
声明一个新类型 T ,它指向 * T 类型的对象,其中:
与此同时,§ 6.49 Using Vector Instructions through Built-in Functions说(强调添加):
在某些目标上,指令集包含SIMD向量指令,这些指令同时对一个大寄存器中包含的多个值进行操作。例如,在x86上MMX,3DNow!和SSE扩展可以这种方式使用。
使用这些扩展的第一步是提供必要的数据类型。这应该使用适当的
来完成typedef
:typedef int v4si __attribute__ ((vector_size (16)));
int
类型指定基本类型,而属性指定变量的向量大小(以字节为单位)。例如,上面的声明使编译器将v4si
类型的模式设置为16字节宽,并分为int大小的单位。对于32位int,这意味着4个4字节的向量,foo的对应模式是V4SI。
vector_size
属性仅适用于整数和浮点标量,但数组,指针和函数返回值与此结构一起使用。仅限大小的幂目前允许两个。
#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));
}
输出:
Ptr: 8
Struct: 128
这与batcrazyptr ptr
本身一致,其对齐要求已更改,而不是其指针,并与文档一致。
我害怕你被迫使用typedef
链,正如你对int4u
所做的那样。有一个单独的属性来指定typedef
中每个指针级别的对齐方式是不合理的。