C# 是否可以使用联锁。是否将交换与位进行比较?

C# 是否可以使用联锁。是否将交换与位进行比较?,c#,arrays,multithreading,task-parallel-library,interlocked,C#,Arrays,Multithreading,Task Parallel Library,Interlocked,我有一个int数组,它跟踪10000个并发任务的完成情况,其中值为1或0。我认为,如果这个数组是一个位数组,并且每个并发线程使用interlocked.CompareExchange(或类似)来更改单个位,那么效率会更高 如果Interlocked没有“位”的重载,我应该如何处理这个问题?我认为您不能使用Interlocked来处理位。我相信,您必须切换到int数组,这样每个位都在自己的int中 互锁。CompareExchange只进行相等的比较,而您只需要比较int中的一个位,除非您使用其他

我有一个int数组,它跟踪10000个并发任务的完成情况,其中值为1或0。我认为,如果这个数组是一个位数组,并且每个并发线程使用interlocked.CompareExchange(或类似)来更改单个位,那么效率会更高


如果Interlocked没有“位”的重载,我应该如何处理这个问题?

我认为您不能使用Interlocked来处理位。我相信,您必须切换到
int
数组,这样每个位都在自己的
int


互锁。CompareExchange
只进行相等的比较,而您只需要比较
int
中的一个位,除非您使用其他并发策略来保护该位所在的
int
的其他更改。您需要线程安全结构来跟踪并发任务。因此,联锁构造总是比锁快(因为它们不需要锁),您应该使用带有整数的
interlocked
-类中的静态方法(例如,0相当于
false
,1相当于
true


Jeffrey Richter的做法与他在第28章“原始线程同步构造”中的书“CLR通过C#”中描述的相同。他还在他的Wintellect.PowerThreading库中介绍了自己的基于互锁结构的锁实现,并对自己的实现和.net framework中包含的实现进行了出色的解释和时间比较。

您可以在循环中使用
互锁。compareeExchange(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;
   }
}

首先,不,所有互锁功能都在内存地址上工作,单个位不可寻址

那么该怎么办呢

我将调查两种选择:

  • 根本不用担心数组:有一个简单的计数器,每次任务完成时,
    InterlockedIncrement
    。要查看是否所有任务都已完成,只需检查值是否已达到10000即可
  • 或者,使用数组,以最小化(错误)数据共享。但是你不应该把它装得太密。走相反的路。确保每个条目都位于单独的CPU缓存线上,这样并行运行的任务就不会在相同的缓存线上发生冲突。(而且,由于所有任务都写入不同的位置,因此它们甚至不必使用昂贵的联锁操作设置“完成”标志。)

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

不在比特级。甚至不确定cpu。我知道在微控制器中会有位带。为什么你认为有一个位数组会更有效?@Jalf我设想检查10000个值是否都是“1”。如果我把它作为一个int,那么我想会有10000个检查。如果我将此作为一个位来执行,我可以执行CPU允许的任意多个位(64位CPU上的64位?)如果您只想检查是否所有10000个任务都已完成,是否考虑使用
倒计时事件
@makerofthings7:您仍然希望孤立地检查每个位(否则它不会被联锁),因此即使可以进行检查,您仍然需要进行10000次检查(不能,因为
interlocked\uuuuuu
函数仅在字节级别工作)我认为使用bits更有效的原因是,我将为每一次写入执行100次读取。换句话说,我将读取10000个整数的数组,对每次写入进行比较。(注意,这只是加载的一个示例,而不是实际的实现)您认为自旋锁会有好处吗?也许是为了在发生争论时作为退路?我不是这方面的专家,但我的直觉是添加
SpinLock
将超过此方法的任何好处。