【问题标题】:Interlocked operations and alignment with _aligned_malloc联锁操作和与 _aligned_malloc 对齐
【发布时间】: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 packalignas 和其他影响对齐的类似编译器指令。想想当一个结构的对齐方式 struct S 中的long l 将无法正确对齐以进行互锁/原子访问。

标签: c multithreading winapi


【解决方案1】:

如果您的结构是对齐的(这是默认设置),那么每个成员都将根据成员类型进行对齐。

malloc 而言,MSVC 的documentation 解释说,在 32 个目标上,内存是 8 字节对齐的,在 64 位目标上是 16 字节对齐的。所以你可以使用malloc

【讨论】:

  • 好的,谢谢。我已经与一位同事讨论过这个问题,他建议 MSDN 强调变量必须是 32 位对齐的原因是,以防有人做一些事情(愚蠢?),比如索引到一个字符数组并将结果转换为 long,然后在联锁功能;你同意吗?
  • 是的,这是一种可能性。另一个是使用打包数据结构。
猜你喜欢
  • 2010-10-30
  • 2016-06-11
  • 1970-01-01
  • 1970-01-01
  • 2015-11-11
  • 2011-06-19
  • 1970-01-01
  • 2016-09-22
  • 2023-04-07
相关资源
最近更新 更多