简体   繁体   English

并行操作批处理

[英]Parallel Operation Batching

Is there built-in support in the TPL (Task-Parallel-Library) for batching operations? 在TPL(任务 - 并行 - 库)中是否有内置支持用于批处理操作?

I was recently playing with a routine to carry out character replacement on a character array using a lookup table ie transliteration: 我最近玩了一个例程,使用查找表即音译在字符数组上进行字符替换:

for (int i = 0; i < chars.Length; i++)
{
    char replaceChar;

    if (lookup.TryGetValue(chars[i], out replaceChar))
    {
        chars[i] = replaceChar;
    }
}

I could see that this could be trivially parallelized, so jumped in with a first stab which I knew would perform worse as the tasks were too fine-grained: 我可以看到,这可能是平凡的并行化,所以跳入第一次刺,我知道会因为任务太细粒度而表现更差:

Parallel.For(0, chars.Length, i =>
{
    char replaceChar;

    if (lookup.TryGetValue(chars[i], out replaceChar))
    {
        chars[i] = replaceChar;
    }
});

I then reworked the algorithm to use batching so that the work could be chunked onto different threads in less fine-grained batches. 然后我重新编写算法以使用批处理,这样就可以将工作分成不同细粒度的不同线程。 This made use of threads as expected and I got some near linear speed up. 这使得线程按预期使用,并且我得到了一些接近线性的加速。

I'm sure that there must be built-in support for batching in the TPL. 我确信必须内置支持TPL中的批处理。 What is the syntax, and how do I use it? 什么是语法,我该如何使用它?

const int CharBatch = 100;
int charLen = chars.Length;

Parallel.For(0, ((charLen / CharBatch) + 1), i =>
{
    int batchUpper = ((i + 1) * CharBatch);

    for (int j = i * CharBatch; j < batchUpper && j < charLen; j++)
    {
        char replaceChar;

        if (lookup.TryGetValue(chars[j], out replaceChar))
        {
            chars[j] = replaceChar;
        }
    }
});

Update 更新

After using @Oliver's answer and replacing Parallel.For with a Parallel.ForEach and a Partitioner the code is as follows: 在使用@Oliver的答案并用Parallel.ForEach和Partitioner替换Parallel.For ,代码如下:

const int CharBatch = 100;

Parallel.ForEach(Partitioner.Create(0, chars.Length, CharBatch), range =>
{
    for (int i = range.Item1; i < range.Item2; i++)
    {
        char replaceChar;

        if (lookup.TryGetValue(chars[i], out replaceChar))
        {
            chars[i] = replaceChar;
        }
    }
});

For better getting your head around you should get the Patterns for Parallel Programming: Understanding and Applying Parallel Patterns with the .NET Framework 4 . 为了更好地了解您的应用,您应该获得并行编程模式:使用.NET Framework理解和应用并行模式4 It's a great source and explains the common ways on how to use the TPL. 它是一个很好的资源,并解释了如何使用TPL的常用方法。

Take a look at page 26 (Very small loop bodies). 看看第26页(非常小的循环体)。 There you'll find this example: 在那里你会发现这个例子:

Parallel.ForEach(Partitioner.Create(from, to), range =>
{
    for (int i = range.Item1; i < range.Item2; i++)
    {
        // ... process i
    }
});

So the missing piece you're searching is the System.Concurrent.Collections.Partitioner . 因此,您正在搜索的缺失部分是System.Concurrent.Collections.Partitioner

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

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