繁体   English   中英

可以使用Interlocked.CompareExchange吗?

[英]Possible to use Interlocked.CompareExchange with a Bit?

我有一个整数数组,该整数数组可以跟踪10,000个并发任务的完成,其值为1或0。我认为,如果此数组是一个Bits数组,并且每个并发线程使用互锁,则效率会更高。 )更改一位。

如果“互锁”没有“位”的重载,我应该如何处理?

您可以在一个循环中使用Interlocked.CompareExchange(ref int, int, int)进行伪造,但我认为这样做不会更有效:

private static void SetBit(ref int valueToUpdate, int bitToSet)
{
   while (true)
   {
      int oldValue = valueToUpdate;
      int newValue = oldValue | bitToSet;
      int result = Interlocked.CompareExchange(ref valueToUpdate, newValue, oldValue);
      if (result == oldValue) break;
   }
}

我不认为您可以使用Interlocked使用位。 我相信,您将不得不切换到一个ints数组,以便每个位都在其自己的int

Interlocked.CompareExchange仅比较是否相等,而您只需要比较该int一小部分,除非您使用其他并发策略来保护该int所在的int的其他更改,否则您无法进行比较。

您需要线程安全的构造来跟踪并发任务的完成。 因此,互锁的构造总是比锁快(因为它们不需要锁),因此您应该使用Interlocked -class中的带有整数的静态方法(例如,0等同于false ,1等同于true )。

杰弗里·里希特(Jeffrey Richter)所做的与他在第28章“原始线程同步构造”中的“通过C#进行CLR”中的描述相同。 他还在Wintellect.PowerThreading库中介绍了基于互锁结构的自己的锁实现,并对自己的实现以及.net框架中的实现进行了出色的解释以及时间比较。

首先,不,所有互锁功能都在存储器地址上运行,并且单个位不可寻址。

那么该怎么做呢?

我将研究两个选择:

  • 根本不用理会数组:拥有一个简单的计数器,并在每次任务完成时对其进行InterlockedIncrement 要查看所有任务是否已完成,只需检查该值是否已达到10,000。
  • 或者,使用数组,以最小化(错误)数据共享。 但是,您不应该尝试将其密集包装。 相反。 确保每个条目最终都位于单独的CPU高速缓存行上,以便并行运行的任务不会争夺相同的高速缓存行。 (然后,由于所有任务都写入不同的位置,因此它们甚至不必通过昂贵的互锁操作来设置“完成”标志。)

我不知道哪一个最快。 如果性能很重要,请进行基准测试。 :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM