关于填充同步结构

时间:2012-12-26 04:41:55

标签: c linux pointers

我已阅读以下网页中有关填充的结构:

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个字节的结构,或者我想念的东西呢?

更新

感谢各种信息!!发帖后问题,我有 谷歌搜索“对齐结构”,看起来像“posix_memalign”似乎是非常正确的函数调用...

2 个答案:

答案 0 :(得分:4)

有两个原因:

  1. 确保结构不跨越缓存边界并占用两个缓存行,因此每次访问需要两次提取和两次无效
  2. 确保每个缓存行只有一个结构,并防止错误共享。
  3. 与高速缓存行开头的对齐提供了两者。将结构填充到与缓存行相同的大小不会提供。

    想象一下,如果你愿意的话,在具有4字节int和8字节操作系统堆对齐以及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);
    

    毫无困难地做出两个保证,因为每个对象都将从某个缓存行的开头开始。

答案 1 :(得分:0)

Nooo,整数变量的sizeof运算符在64位系统中仍然返回4。 Bytesize是实现定义的。