InterlockedDecrement 使用 XADD 但 InterlockedIncrement 使用 INC?

问题描述 投票:0回答:2

我正在使用 boost C++ 库调试一些代码,该库使用 Windows

InterlockedDecrement
InterlockedIncrement

在输出的程序集中,InterlockedIncrement 使用

LOCK INC
,而 InterlockedDecrement 使用
LOCK XADD

为什么他们不都使用

LOCK XADD

(这是在Win 7 64,64位编译和MSVC 11上)

c++ windows x86 atomic interlocked
2个回答
4
投票

INC
指令的编码较短。 您可以使用
LOCK XADD
来实现两者,但代码会占用更多内存空间。 一旦它们变成微指令,它们可能是相同的。

现在,为什么不使用

LOCK DEC

我的猜测是有问题的代码是这样的:

InterlockedIncrement(&refcount);
...

if (InterlockedDecrement(&refcount) == 0)
    ...

这是引用计数的常见模式。 在这种情况下,您不能使用

LOCK DEC
,因为
LOCK DEC
不会返回结果值。

// WRONG WRONG WRONG WRONG
InterlockedDecrement(&refcount);
    // <-- another thread might modify refcount here
if (refcount == 0)
    ...

0
投票

与 Dietrich Epp 暗示的相反,LOCK DEC 确实修改了零标志。因此,如果您只是使用 InterlockedDecrement 进行引用计数,唯一重要的是它是否为零,您可以使用 LOCK DEC 实现 InterlockedDecrement,事实上这就是它在 Windows 95 和 Windows NT 3.51 上的实现方式和更早的时候。这些操作系统仍然支持80386,但它没有XADD指令,因此必须使用INC和DEC。 Windows NT 系列放弃了对 80386 的支持,因此 Windows NT 4 及更高版本都使用 XADD 来执行这两种操作。我知道 Windows XP 上是这样的,而且我刚刚在 Windows 10 上验证了它,所以 Intrigued 66 声称 InterlockedIncrement 仍然使用 INC 肯定是错误的。我猜他反汇编了一些直接使用指令而不是 API 调用的库代码。无论是哪一段代码,它都不需要结果,因此使用了 LOCK INC。在最常见的用例中,您可以使用 LOCK DEC 而不是 InterlockedDecrement,并且生成的代码将比具有开销的 API 调用更快这需要。

© www.soinside.com 2019 - 2024. All rights reserved.