代码之家  ›  专栏  ›  技术社区  ›  Rauhotz

读写器锁定与监视器

  •  5
  • Rauhotz  · 技术社区  · 16 年前

    我有一个 IDictionary<TKey,TValue> 内部持有其他 Dictionary<TKey, TValue> 并通过invidual子字典密钥的散列码分发这些插入。有了16个子字典,4核机器上的冲突数量非常少。

    对于并行插入,我用 ReaderWriterLockSlim ,仅锁定单个子字典:

      public void Add(TKey key, TValue value)
            {
                int poolIndex = GetPoolIndex(key);
                this.locks[poolIndex].EnterWriteLock();
                try
                {
                    this.pools[poolIndex].Add(key, value);
                }
                finally
                {
                    this.locks[poolIndex].ExitWriteLock();
                }
            }
    

    当插入带有四个线程的项目时,我只得到32%的CPU使用率和糟糕的性能。因此,我用一个监视器(即 lock 关键字)。 现在CPU使用率接近100%,性能提高了一倍多。

    我的问题是:为什么CPU使用量增加了?碰撞的次数不应该改变。是什么让readerwriterlock.enterwritelock等了这么多次?

    3 回复  |  直到 16 年前
        1
  •  13
  •   vboctor    16 年前

    对于只写加载,监视器要比readerwriterlockslim便宜,但是,如果您模拟读+写加载,其中读大于写,那么readerwriterlockslim应该不执行监视器。

        2
  •  0
  •   Dmitri Nesteruk    16 年前

    我不是专家,但我的猜测是RWLS更倾向于激烈的竞争(例如,数百个线程),而 Monitor 更倾向于一次性同步问题。

    我个人使用 TimerLock 使用的类 Monitor.TryEnter 带有超时参数。

        3
  •  0
  •   iny    16 年前

    你怎么知道是什么导致了糟糕的表现?你不能去猜测,唯一的方法是做一些分析。

    如何处理父集合的锁定,还是它是常量?

    也许您需要添加一些调试输出,看看到底发生了什么?