当我尝试使用不同的互斥体变体时,最后我找到了2个最快的基元。
一个是基于InterlockedExchange(众所周知的方法)
Access:
while InterlockedExchange(AccessFlag, 1) <> 0 do
Release:
InterlockedExchange(AccessFlag, 0)
另一个是基于事件的。
Init:
Event = CreateEvent(Null, false, true, Null);
Access:
WaitForSingleObject(Event, INFINITE)
Release:
SetEvent(Event)
InterlockedExchanged-based总是最快,但是在失败的情况下它没有睡觉。另一方面,它在单个物理处理器(核心)或多个核心上都有很大的作用。虽然单核测试的好处是,如果我在循环内添加Sleep(0),则没有失败。
基于事件在等待睡眠时非常棒,但是当我测量性能时,我注意到如果它们驻留在单个物理处理器上(使用相同值调用的SetThreadAffinityMask或测试时,使用这种类型的互斥锁的几个线程执行速度更快)单核计算机)而不是不同的处理器。根据处理器的类型,这从x4(iCore 5)到x8(Xeon)不等。
Xeon的一些统计数据
3个线程,每个增加一个变量10(10,000,000步),每次增加时使用互斥锁访问它。
多处理器,基于InterlockedExcchange的
344毫秒/每位女士:87,209 / while循环失败:2,487,376(占3的总步数的8%) 线程,Sleep(0)存在,但可能对多处理器线程无用)
多处理器,基于事件
6187毫秒/每位女士:4,848
单处理器,基于InterlockedExcchange的
281毫秒/每位女士: 106,761 / while循环失败:0(循环内的Sleep(0));
单处理器,基于事件
765毫秒/每位女士:39,215
我认为真正的核心间同步会有一些损失。但是我想结婚&#34; InterlockedExchange方法的完美表现与基于事件的方法的正确性(&#34;睡眠,如果你不工作&#34;)。这可能吗?
答案 0 :(得分:1)
我认为这样做的一种常见方法是仅在有限次数的尝试中使用CAS步骤。如果您的情况没有及时成为现实,那么您将经历“更昂贵”的基于事件的解决方案的开销。