【发布时间】:2018-10-12 14:08:00
【问题描述】:
我担心对齐和Interlocked 操作。再次。这些函数的文档指出,我们要更新的变量应该在 32 位边界上对齐,并且我们可以通过 _aligned_malloc 实现这一点。很好。
所以我有这个小测试程序:
struct S
{
char c;
long l;
}an_S;
printf("%p, %p", (void*)(&(an_S.c)), (void*)(&(an_S.l)));
在释放模式下,它的输出总是给我一个长地址,它在字符地址之后 4 个字节,因此它从 32 位边界开始。
1) 这纯粹是偶然的,还是我可以依赖它,因此不需要_aligned_malloc?
2) 如果我必须使用aligned_malloc,有人可以说明如何使用吗?我已经阅读了https://msdn.microsoft.com/en-us/library/8z34s9c6.aspx 的文档,但这似乎没有显示如何为“分配”的内存分配一个值......
3) (假设我确实需要aligned_malloc)如果我想要一个结构数组,它具有像上面这样的长变量,需要通过互锁操作进行操作,我是否需要添加某种构造函数进行设置还是有更简单的方法?
4) 我在 Google 上搜索了 _aligned_malloc+interlockedCompareExchange,结果只买回了 70 个结果。这告诉我,使用InterlockedCompareExchange(62,800 个结果)的大部分代码是错误的,或者_aligned_malloc 不是必需的。有人可以澄清一下吗?
【问题讨论】:
-
这里不需要任何
_aligned_malloc。并且long l将在 4 个字节上对齐,如果您不使用#pragma(pack, N)其中N小于 4(2 或 1)。根本上,根据您最初的问题,您需要绝对的 else - rundown-protection -
如果你使用对齐的结构,你可以依赖它。这是默认设置。局部变量也对齐。 malloc 也很好。除非你想要不寻常的对齐方式,比如 16 字节。
-
在
struct S的内部,long l将距离char c的开头 X 字节,其中 X 是struct S的对齐方式。但是,这并不能保证struct S的实例,如an_s,分配在对齐的内存地址,因此l可能并不总是在对齐的32 位边界。这取决于声明struct S时使用的对齐方式,以及分配struct S的代码的对齐方式。 -
@Remy Lebeau,我现在很困惑。 David Heffernan 在下面说结构默认对齐。我不是说你错了,我是说我不知道什么是对的:\ 此外,en.wikipedia.org/wiki/Data_structure_alignment 告诉我结构中每个成员的类型通常都有默认对齐方式 - 所以如果第一个成员是对齐的,那么所有其他成员都将跟随对齐?
-
@Wad 用于 default 对齐。查看
#pragma pack、alignas和其他影响对齐的类似编译器指令。想想当一个结构的对齐方式 struct S 中的long l将无法正确对齐以进行互锁/原子访问。
标签: c multithreading winapi