我使用两个不同的库来执行原子操作。我创建了一个二叉树节点结构,其中包含一个键(8个字节)和指向左右两个子节点的指针(每个8字节)。
预期的节点大小为24个字节。如果我使用Intel TBB库,我就会得到预期的行为。但是如果我使用HP的atomic_ops库,我会看到节点大小为32。
汇编者使用:
gcc4.6,gcc4.8,国际商会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。
发布于 2015-10-16 19:30:40
为什么非标准的atomics实现应该在它们所使用的数据类型中达成一致,大小和对齐可能是不同的,原因并不多。取决于编译器标志,在某些情况下,其中一个甚至可以使用锁定版本,而另一个版本则使用本机指令。别把它们混在一起。
现代C和C++都有内置于语言中的atomics,如果可以的话,可以使用它们。它们甚至被设计成两者之间的兼容。
发布于 2015-10-20 01:24:56
正如在comment中指出的,节点32::子节点使用
typedef __m128 double_ptr_storage;因此编译器必须在第一个key字段之后添加额外的填充,因为它的大小只有8个字节,因此需要另外8字节的填充空间来修复对齐。当您添加第三个字段时(我猜到最后?)为了在数组中保持对齐,编译器必须添加进一步的填充。
https://stackoverflow.com/questions/33177282
复制相似问题