使用Visual C ++(2010)在64位版本中生成CMPXCHG(无LOCK)

时间:2013-01-09 21:09:59

标签: visual-studio-2010 assembly 64-bit compare-and-swap

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

InterlockedCompareExchange生成LOCK CMPXCHG。 LOCK部分带有副作用,例如高速缓存未命中,总线锁定以及与其他CPU争用的可能性,所有这些都很好,但考虑到环境,感觉就像是一个过度的过剩。由于竞争线程在同一个CPU上运行,我假设LOCK可以被丢弃,我进一步假设它应该导致性能提高。

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

-

我知道如何使用32位版本的内联汇编生成CMPXCHG。另外,根据this SO thread我也知道如何处理64位版本,但是作为函数调用。

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

-

感谢。

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

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

我怀疑*如果不使用汇编,你将自己获得CMPXCHG指令。如果该区域非常重要,请使用Interlocked内在函数,反汇编输出,删除LOCK覆盖前缀并将其链接(我将对32和64位变体执行此操作,因为内联ASM为{{3}因为它总是被视为不安全,导致额外的保护插入,这可能比调用外部版本更糟糕。在正面,它还将为您提供更统一的代码布局。)

我还建议您使用不带LOCK的两种解决方案进行配置,因为大多数较新的Intel CPU都实现了缓存级锁定,这大大降低了锁定的性能影响({{第8章] 3}}提供了对总线锁定的确切影响的健康洞察力。)

*“怀疑”我的意思是:它不作为一个明确的内在存在,并且使用编译器强制技巧非常脆弱,而不是我知道任何强制{{{ 1}}或XCHGCMPXCHG除外,用作对齐NO-OP)。