0

我需要在同一 CPU 上运行的多个线程的上下文中使用 CAS 函数(假设所有线程都静态地粘合到选定的 CPU,通过SetThreadAffinityMask)。

InterlockedCompareExchange生成LOCK CMPXCHG。LOCK 部分会带来一些副作用,例如缓存未命中、总线锁定以及与其他 CPU 争用的可能性,所有这些都很好,但考虑到这种情况,感觉就像是一种奢侈的过度。由于竞争线程在同一个 CPU 上运行,我假设可以删除 LOCK,并且我进一步假设它应该会提高性能。

所以这是我的第一个问题——我假设正确吗?

--

我知道如何使用 32 位版本的内联汇编生成 CMPXCHG。此外,根据这个 SO 线程,我也知道如何处理 64 位版本,作为函数调用。

我不明白,这是我的第二个问题,是如何生成它的内联版本。

--

谢谢。

4

2 回答 2

1

不是要回答我自己的问题,而是要描述一种解决方法。

对于布尔变量上的 CAS,可以回退到_bittestandset,这比 CMPXCHG 慢,但在 VS2010 中具有内在形式。

于 2013-01-10T08:18:28.417 回答
1

这真的更像是一个评论,但空间有点太有限了......

我怀疑*您会CMPXCHG在不使用汇编的情况下自行获得说明。如果该区域如此关键,请使用 Interlocked 内在函数,反汇编输出,删除LOCK覆盖前缀并将其链接(我会为 32 位和 64 位变体执行此操作,因为内联 ASM在 MSVC 中不是最优的,因为它总是被视为不安全,导致插入额外的保护,这可能比调用外部版本更糟糕。从好的方面来说,它也会给你一个更统一的代码布局)。

我还建议您对这两种解决方案进行概要分析LOCK带总线锁定的确切效果)。

*我所说的“怀疑”是指:它不作为显式内在存在,并且使用编译器强制技巧非常脆弱,并不是说我知道任何用于强制发射XCHGor CMPXCHG(除了XCHG (E)AX,(E)AX,用作对齐 NO -OP)。

于 2013-01-10T10:02:42.763 回答