c# - PLINQ遍历chunk分区的实现

标签 c# multithreading linq plinq

我遇到了实现 ContiguousChunkLazyEnumerator 类,它被 PLINQ 使用( block 的遍历是用这个迭代器执行的)。 MoveNext 方法使用线程安全访问源IEnumerator(通过使用特定的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 应该会破坏任何性能优势。我的假设是唯一工作线程的连续访问应该以相同的速度工作。

最佳答案

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

lock每个 block 都完成,因此多个线程将在 block 之间相互让步。

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

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

关于c# - PLINQ遍历chunk分区的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41672476/

相关文章:

c# - C# 中的控制台和 Windows 窗体

c# - 尝试从 2D 图像准确测量 3D 距离

java - 拥有线程的对象意味着什么?

java - 需要一个 Java 方法的解决方案,该方法返回一个字符串值,以便在 JVM 中仅执行 n 个线程

c# - 使用 Entity Framework 添加多个对象时如何获取多个对象的标识?

c# - 无法在 WinForms 中右侧添加 DataGridViewButtonColumn

c# - 如何在没有回调的情况下异步发出 Web 请求

Android - 如何在另一个 Activity 期间暂停线程?

C# : How to compare two collections (System. Collection.Generic.List<T>) 使用 Linq/Lambda?

asp.net-mvc - 如何绑定(bind)从具有 linq 到 sql asp.net mvc 的模型中排除多个属性