Parallel.For性能

时间:2013-08-13 07:45:47

标签: c# task-parallel-library

此代码来自Microsoft文章http://msdn.microsoft.com/en-us/library/dd460703.aspx,稍作修改:

        const int size = 10000000;
        int[] nums = new int[size];
        Parallel.For(0, size, i => {nums[i] = 1;});
        long total = 0;

        Parallel.For<long>(
            0, size, () => 0,
            (j, loop, subtotal) =>
            {
                return subtotal + nums[j];
            },
            (x) => Interlocked.Add(ref total, x) 
        );

        if (total != size)
        {
            Console.WriteLine("Error");
        }

非并行循环版本是:

        for (int i = 0; i < size; ++i)
        {
            total += nums[i];
        }

当我使用StopWatch类测量循环执行时间时,我发现并行版本慢了10-20%。测试在Windows 7 64位,Intel i5-2400 CPU,4核,4 GB RAM上完成。当然,在Release配置中。

在我的真实程序中,我正在尝试计算图像直方图,并行版本运行速度慢10倍。当每次循环调用非常快时,这种计算任务能否与TPL成功并行化?

修改

最后,当将整个图像划分为若干个块时,我设法使用Parallel.For节省了超过50%的直方图计算执行时间。每个循环体调用现在处理整个块,而不是一个像素。

1 个答案:

答案 0 :(得分:4)

因为Parallel.For应该用于有点神圣的事情,而不是简单数字的总和!只需使用代理(j, loop, subtotal) =>就足以让10-20%的时间更长。我们甚至没有谈到线程开销。看到针对周期中代表夏天的一些基准并且不仅要查看“真实世界”时间,还要查看CPU时间,这将会很有趣。

我甚至添加了一个与“{1}}委托做同样事情的”简单“委托的比较。

嗯......现在我的PC上有一些32位的数字(AMD六核)

Parallel.For<>

并行在壁挂时间稍微快一点,但在处理器时间慢了8倍: - )

但是64位:

32 bits
Parallel: Ticks:      74581, Total ProcessTime:    2496016
Base    : Ticks:      90395, Total ProcessTime:     312002
Func    : Ticks:     147037, Total ProcessTime:     468003

修改后的代码:

64 bits
Parallel: Ticks:     104326, Total ProcessTime:    2652017
Base    : Ticks:      51664, Total ProcessTime:     156001
Func    : Ticks:      77861, Total ProcessTime:     312002