2012-12-26 41 views
1

我看了一下填充在以下网页结构:关于填充同步结构

http://software.intel.com/sites/default/files/m/2/c/d/3/9/25602-17689_w_spinlock.pdf

,因为它描述的:它暗示下面的语句做填充同步结构:

struct syn_str { int s_variable; }; 
void *p = malloc (sizeof (struct syn_str) + 127); 
syn_str * align_p = (syn_str *)((((int) p) + 127) & -128); 

什么我想到的是,这是可以做到像要容易得多:

struct syn_str { int s_variable; char padx[124] ; } in 32-bit OS 

struct syn_str { int s_variable; char padx[120] ; } in 64-bit OS 

因为所有它想要做的是填写的结构充满128个字节,或者说我在为这样错过?

更新:

感谢所有类型的信息!后问题后,我有 用Google搜索“排列结构”,看起来像“posix_memalign”似乎是相当正确的函数调用来使用......

+0

这是为了对齐,124或120的填充不一定足够好,它取决于'malloc'的对齐。 –

回答

4

有两个原因:

  1. 要确保结构不跨越高速缓存边界,并采取了两个高速缓存行,因此需要两个取和每次访问
  2. 2张废票要使确保每个缓存行只有一个结构,并防止错误共享。

与高速缓存行开头的对齐提供了两者。将结构填充为与高速缓存行相同的大小不提供。

可以想象,如果你愿意,用4字节int和8字节OS堆对准和128字节的高速缓存行的系统(非常常见)上的结构如下:

struct bare 
{ 
    int x, y, z, u, v, w; 
}; 

仅仅添加填充,如:

struct padded 
{ 
    int x, y, z, u, v, w; 
    char pad[128 - 6 * sizeof (int)]; // 104 
}; 

不阻止该对象在地址112被分配,其中x, y, z, u落入一个页面和v, w到的第二个。所以第一个目标被违反了。另一个对象可以在地址248处分配,x, y与前一个对象的v, w位于同一缓存行中。所以第二个目标被违反了。

然而,

char* block = malloc(sizeof (bare) + 127); 
bare* p = reinterpret_cast<bare*>(reinterpret_cast<intptr_t>(block + 127) & ~127); 

使得无论保证没有困难,因为每个对象将在一些高速缓存行的起点开始。

0

拿去,对于整型变量sizeof操作符仍然在64位系统返回4。字节大小是实现定义的。

+0

它因实施而异。但重要的是,正确的填充是'(alignment-1)',而不是'(alignment - sizeof struct)' –