InterlockedCompareExchange - 确切的对齐要求是啥以及如何执行?

Posted

技术标签:

【中文标题】InterlockedCompareExchange - 确切的对齐要求是啥以及如何执行?【英文标题】:InterlockedCompareExchange - what are the exact alignment requirements and how can they be enforced?InterlockedCompareExchange - 确切的对齐要求是什么以及如何执行? 【发布时间】:2016-02-12 16:51:11 【问题描述】:

我无法理解 MSDN 文档对 Interlocked Variable Access 系列函数的含义。 我使用InterlockedExchange 进行设置,InterlockedCompareExchange 用于获取多个线程使用的成员变量。

该成员在一个 1 字节的打包类中:

#pragma pack(1)
class MyClass 
    char _;
    long m_MyMember;
    // ...

所以成员是由设置的

InterlockedExchange(&m_MyMember, 1);

得到了

long value = InterlockedCompareExchange(&m_MyMember, 0, 0);

InterlockedExchange 文档没有以任何方式提及对齐 (Strg+F "align"),但 InterlockedCompareExchange 确实:

此函数的参数必须在 32 位边界上对齐;否则,该函数将在多处理器 x86 系统和任何非 x86 系统上运行不可预测。

但是,据我了解,参数都是堆栈变量,因为可以重写上面的调用

long *ptr  = &m_MyMember;
long zero  = 0;
long value = InterlockedCompareExchange(ptr, zero, zero);

所以我们有块本地自动存储类变量。无论 m_MyMember 所在的类如何,所有 4 字节都完美对齐。 当然,我认为这是错误的,这意味着 ptr 后面的地址必须在 4 字节边界上对齐。

所以我的问题是:

    InterlockedExchange 是否真的与对齐无关,或者这是文档中的漏洞? 您能否确认不是字面意义上的参数,而是 long* 后面的地址必须是 4 字节对齐的(我不能假设其他参数为什么不能是 4 字节对齐,因为它们是堆栈变量)? 如果对 2 的回答是:如何解决?更改周围类的对齐方式不是一种选择,c++ 11 atomic 或 boost 也不是(所有这些都是由于公司限制和 msvc10 到 msvc14 所需的可编译性)。

我考虑过声明 m_MyMember volatile 并使用临界区来访问它。虽然我希望更好地正确声明 m_MyMember 以根据需要对齐,因为这些互锁变量访问函数都围绕给定的代码库,我不想为每个变量添加额外的伴随 CS .

【问题讨论】:

为什么-哦-你为什么要这样做?在 x86 和 x64 上,InterlockedExchange() 生成 XCHG 指令,它始终是原子的。未对齐变量的成本是您必须自己衡量的,我猜是胳膊和腿。 您声称,由于参数在堆栈上,因此记录的合同得到满足……这是对所使用的语言的吹毛求疵。显然,文档意味着指针必须对齐。没有办法让自己脱离合同! @Hans Passant:由于我必须使用遗留接口。同样,这不是衡量的主题,而是符合规范的代码。我已经在 SO 的其他地方阅读了生成的指令(以及硬件异常,请参阅 csgordons 对***.com/questions/881820/… 的评论),但我缺乏评估这些陈述的洞察力。 @usr:是的,这也是我的假设。在 MSDN 的那个关键地方使用这种松散的措辞真的很烦人。 【参考方案1】:

真正的限制不是微软的,而是硬件。为了原子地改变东西,它必须对齐(指针)。

对于临界区或 STD::atomic 的成员也是如此

在不重新对齐类的情况下,如果您可以使用 interlock 变量来保证与类的 4 字节对齐,那么这应该可以工作

【讨论】:

我的意思是我会使用临界区来保证唯一的所有权,然后读写 volatile 变量的内容。或者您所说的“关键部分的成员”是什么意思?对不起,我不明白你的最后一句话:“如果不重新对齐类,如果你可以使用联锁变量来保证与类的 4 字节对齐,那么应该可以”

以上是关于InterlockedCompareExchange - 确切的对齐要求是啥以及如何执行?的主要内容,如果未能解决你的问题,请参考以下文章