我已在以下网页中阅读到有关结构填充的内容:
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个字节填充一个完整的结构,或者我在这方面遗漏了什么?
更新:
谢谢你提供的所有信息!!提问后,我有
谷歌搜索“align structure”和看起来像“posix_memalign”似乎是非常正确的函数调用使用…

最佳答案

有两个原因:
为了确保结构不会跨越缓存边界并占用两条缓存线,因此每次访问需要两次获取和两次失效
以确保每个缓存线只有一个结构,并防止错误共享。
与缓存线的开头对齐可以同时提供这两种功能。将结构填充到与缓存线相同的大小两者都不提供。
想象一下,如果您愿意,在一个具有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);

使这两个保证都没有困难,因为每个对象都将从某个缓存线的开头开始。

关于c - 关于填充同步结构,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14036074/

10-14 16:10
查看更多