并行操作批处理 [英] Parallel Operation Batching

查看:134
本文介绍了并行操作批处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TPL(任务并行库)中是否有对批处理操作的内置支持?

Is there built-in support in the TPL (Task-Parallel-Library) for batching operations?

我最近正在玩一个例程,使用查找表(即音译)对字符数组进行字符替换:

I was recently playing with a routine to carry out character replacement on a character array using a lookup table i.e. 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.

我确定TPL中必须有对批处理的内置支持.语法是什么,如何使用?

I'm sure that there must be built-in support for batching in the 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;
        }
    }
});

更新

使用@Oliver的答案并将Parallel.For替换为 Parallel.ForEach和分区程序,代码如下:

After using @Oliver's answer and replacing Parallel.For with a Parallel.ForEach and a Partitioner the code is as follows:

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. It's a great source and explains the common ways on how to use the TPL.

看看第26页(非常小的线圈体).在那里,您将找到以下示例:

Take a look at page 26 (Very small loop bodies). There you'll find this example:

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

因此,您要搜索的丢失的部分是 System.Concurrent.Collections.Partitioner .

So the missing piece you're searching is the System.Concurrent.Collections.Partitioner.

这篇关于并行操作批处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆