【发布时间】:2015-10-16 18:29:02
【问题描述】:
我正在使用两个不同的库来执行原子操作。我创建了一个二叉树节点结构,其中包含一个键(8 个字节)和指向左右子节点(每个 8 个)的指针。
预期的节点大小为 24 字节。 如果我使用英特尔 TBB 库,我会得到预期的行为。但如果我使用 HP 的 atomic_ops 库,我会看到节点大小为 32。
使用的编译器:
gcc4.6、gcc4.8、icc 2013
机器架构:x86_64
代码:
#include<stdio.h>
#include<stdlib.h>
#include<tbb/atomic.h>
#include<atomic_ops.h>
struct node24
{
unsigned long key; //size 8
tbb::atomic<struct node*> child[2]; //size 2*8=16
};
struct node32
{
unsigned long key; // size 8
AO_double_t child; // size 16
};
int main()
{
printf("TBB node size: %d\n",sizeof(node24));
printf("HP atomicOps node size: %d\n",sizeof(node32));
}
输出
$ ./foo.o
TBB node size: 24
HP atomicOps node size: 32
编辑
我的假设是node24 的大小四舍五入到最接近的 8,而node32 的大小四舍五入到最接近的 16(AO_double_t 的大小)。所以我添加了一个额外的value 变量(8 字节)以使节点大小为 32。现在我预计node32 的大小为 32 但它变成了 48。我不明白为什么额外的 16 字节填充当它已经在 32 处对齐时。
【问题讨论】:
-
我怀疑有些对齐问题,试着把钥匙放在最后。
-
试过了。没有变化。
-
尝试添加一个 static_assert(sizeof(AO_double_t)==16, "is not 16");
-
是的。它通过了静态断言。
-
所以我会假设问题出在代码
#if ((defined(__x86_64__) && __GNUC__ >= 4) || defined(_WIN64)) \ && !defined(__ILP32__) # include <xmmintrin.h> typedef __m128 double_ptr_storage;中,__m128 应该对齐 16。