我使用两个不同的库来执行原子操作。我创建了一个二进制树节点结构,其中包含一个键(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.我不明白为什么当已经在32处对齐时,额外的16个字节的填充。
答案 0 :(得分:0)
原子的非标准实现在他们使用的数据类型中应该达成一致的原因没有多少,大小和对齐可能不同。根据编译器标志,在另一个使用本机指令的情况下,甚至可以使用锁定版本。只是不要混合它们。
现代C和C ++具有内置于语言中的原子,如果可以的话,可以使用它们。它们甚至被设计成在两者之间兼容。
答案 1 :(得分:0)
正如comment中所指出的,node32 :: child是使用
定义的typedef __m128 double_ptr_storage;
并且它具有16的对齐。因此编译器必须在第一个key
字段之后添加额外的填充,因为其大小仅为8个字节,需要另外8个字节的填充空间来修复对齐。当你添加第三个字段(我假设到最后?)时,编译器必须添加进一步的填充以便在数组中保持对齐。