在PLINQ中遍历块分区的实现

时间:2017-01-16 08:49:40

标签: c# multithreading linq plinq

我遇到了实现ContiguousChunkLazyEnumerator类,它由PLINQ使用(使用此迭代器执行块的遍历)。 MoveNext方法使用对源IEnumerator的线程安全访问(通过使用speficied lock),此外,它还保存了对内部缓冲区的访问结果。这是一段简短的代码:

lock (m_sourceSyncLock)
{
// Some .net stuff
    try
    {
        for (; i < mutables.m_nextChunkMaxSize && m_source.MoveNext(); i++)
        {
        // Read the current entry into our buffer.
        chunkBuffer[i] = m_source.Current;
        }
    }
// Some .net stuff
}

这样的迭代器将由工作线程使用(N个工作线程使用相同的迭代器)。但我真的不明白这种并行方法的好处。在此上下文中使用lock应该可以消除任何性能优势。我的假设是,唯一的工作线程的等权访问应该以相同的速度工作。

1 个答案:

答案 0 :(得分:3)

这是因为使用PLINQ可以优化项目的并发处理,而不是项目的并发枚举。

每个块完成繁重的lock,因此多个线程将在块之间相互产生。

如果你有一个IEnumerable可以快速枚举(例如List<T>,那么这真的很闪耀,实际上,List<T>有内部优化,所以不是最好的例子) ,并希望对结果进行一些缓慢的计算工作。

此代码用于创建分区数据,然后由多个线程使用。虽然它是线程安全的,但它不应该是最快的并发枚举。它针对数据局部性进行了优化。