什么(如果有的话)是 x86 asm 的 C# 等价物 xchg
指令?
使用该命令,imo 是一个真正的交换(与 Interlocked.Exchange
不同),我可以简单地原子交换两个整数,这正是我真正想要做的。
更新:
基于我的建议的示例代码。后缀为“_V”的变量被修饰为volatile:
// PART 3 - process links
// prepare the new Producer
address.ProducerNew.WorkMask_V = 0;
// copy the current LinkMask
address.ProducerNew.LinkMask_V = address.Producer.LinkMask_V;
// has another (any) thread indicated it dropped its message link from this thread?
if (this.routerEmptyMask[address.ID] != 0)
{
// allow all other bits to remain on (i.e. turn off now defunct links)
address.ProducerNew.LinkMask_V &= ~this.routerEmptyMask[address.ID];
// reset
this.routerEmptyMask[address.ID] = 0;
}
// PART 4 - swap
address.ProducerNew = Interlocked.Exchange<IPC.Producer>(ref address.Producer, address.ProducerNew);
// PART 5 - lazily include the new links, make a working copy
workMask = address.Producer.LinkMask_V |= address.ProducerNew.WorkMask_V;
注意惰性更新。
最佳答案
这是 CLR 中 Interlocked.Exchange() 的可能实现,从 SSCLI20 源代码复制而来:
请注意,函数名称中的 UP 表示 UniProcessor。这在 SMP/多核系统上不是原子的。此实现将仅由 CLR 在单核系统上使用。
FASTCALL_FUNC ExchangeUP,8
_ASSERT_ALIGNED_4_X86 ecx
mov eax, [ecx] ; attempted comparand
retry:
cmpxchg [ecx], edx
jne retry1 ; predicted NOT taken
retn
retry1:
jmp retry
FASTCALL_ENDFUNC ExchangeUP
它优于使用 XCHG,因为此代码无需总线锁定即可工作。 xchg
有一个隐含的 lock
前缀,所以与 xadd
或 cmpxchg
不同,它不能被省略核心系统仍然在一条指令中执行操作,以使其相对于中断(以及单处理器上的其他线程)具有原子性。
奇怪的跳跃代码是在分支预测数据不可用的情况下进行的优化。毋庸置疑,在芯片制造商的慷慨帮助下,与非常优秀的软件工程师多年来深思熟虑的工作相比,试图做得更好是一项艰巨的任务。
关于c# - 如何在 C# 中以原子方式交换 2 个整数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3855671/