我需要CAS函数在同一CPU上运行的多个线程的上下文中使用(假设所有线程通过SetThreadAffinityMask
静态粘贴到选定的CPU)。
InterlockedCompareExchange
生成LOCK CMPXCHG。 LOCK部分带有副作用,例如高速缓存未命中,总线锁定以及与其他CPU争用的可能性,所有这些都很好,但考虑到环境,感觉就像是一个过度的过剩。由于竞争线程在同一个CPU上运行,我假设LOCK可以被丢弃,我进一步假设它应该导致性能提高。
所以这是我的第一个问题 - 我是否正确假设?
-
我知道如何使用32位版本的内联汇编生成CMPXCHG。另外,根据this SO thread我也知道如何处理64位版本,但是作为函数调用。
我不明白,这是我的第二个问题,就是如何生成内联版本。
-
感谢。
答案 0 :(得分:1)
不要回答我自己的问题,而是要描述各种各样的解决方法。
对于布尔变量上的CAS,可以回退到_bittestandset
,这比CMPXCHG慢,但在VS2010中有一个内在形式。
答案 1 :(得分:1)
这真的是一个评论,但空间有点太限......
我怀疑*如果不使用汇编,你将自己获得CMPXCHG
指令。如果该区域非常重要,请使用Interlocked内在函数,反汇编输出,删除LOCK
覆盖前缀并将其链接(我将对32和64位变体执行此操作,因为内联ASM为{{3}因为它总是被视为不安全,导致额外的保护插入,这可能比调用外部版本更糟糕。在正面,它还将为您提供更统一的代码布局。)
我还建议您使用不带LOCK
的两种解决方案进行配置,因为大多数较新的Intel CPU都实现了缓存级锁定,这大大降低了锁定的性能影响({{第8章] 3}}提供了对总线锁定的确切影响的健康洞察力。)
*“怀疑”我的意思是:它不作为一个明确的内在存在,并且使用编译器强制技巧非常脆弱,而不是我知道任何强制{{{ 1}}或XCHG
(CMPXCHG
除外,用作对齐NO-OP)。