0

网上有人说下面的C#代码不能转换成一些Parallel.for(多核系统)是这样吗?如果是,是否有更好的方法来进一步优化它。谢谢

            for (int i = 0; i < 4; i++)
            {
                var tmp = i;
                tasks[i] = Task.Factory.StartNew(() => Console.WriteLine(tmp));
            }
4

3 回答 3

1

好吧,你最后没有 a Tast.WaitAll(tasks),这Parallel.For对你有用,所以你并没有完全做Parallel.For正在做的事情(除非你没有把代码放在你的问题中。如果是这样,那么下一行就是你的代码看起来像一个 Parallel.For 循环)

Parallel.For(0,4, (i) => Console.WriteLine(i));

除此之外,我不明白为什么不能将其转换为 Parallel.For。该人给出了无法转换它的什么原因?

于 2013-02-05T13:40:01.603 回答
0

因为我们没有外部循环代码,所以我在这里暗中尝试。如果您只是测量总体平均运行时间,则不需要存储任务,您可以使用类似这样的方法来测量串行和并行版本:

var iterations = 100;
var stopwatch = new Stopwatch();

// Run Serial version
stopwatch.Start();    
for(int i = 0; i < iterations; i++)
{
    for (int i = 0; i < 4; i++)
    {
        Console.WriteLine(tmp);
    }
}

stopwatch.Stop();
var serialTime = stopwatch.ElapsedMilliseconds;
stopwatch.Reset();

// Run parallel version
stopwatch.Start();

for(int i = 0; i < iterations; i++)
{
    Parallel.For(0,4, (i) => Console.WriteLine(i));    
}

stopwatch.Stop();

var parallelTime = stopwatch.ElapsedMilliseconds;

Console.WriteLine("Serial took  : {0}ms", serialTime / (double)iterations);
Console.WriteLine("Parallel took: {0}ms", parallelTime / (double)iterations);

由于工作量很轻,这可能不是衡量加速的一个很好的测试。您可以尝试调用具有更多开销的函数或Thread.Sleep模仿更多工作。另请参阅我在此 StackOverflow 问题上的回答,了解如何在 C# 中测量 Amdahl 定律加速。

于 2013-02-05T21:13:55.080 回答
0

首先,关于您报告的错误:

未处理的异常:System.AggregateException:发生了一个或多个错误。System.ArgumentExcpetion:任务数组包含至少一个空元素参数名称:Tasks

错误很明显,它是由您的Task.WaitAll调用引发的 - 它表示您的tasks数组中的任务槽之一为空。

其次,衡量性能Console.WriteLine不好有两个原因:

  1. 工作量太轻:我猜设置开销会使实际工作相形见绌;
  2. Console.WriteLine是同步的——这意味着所有任务都将开始,然后立即同步——在这种情况下,使用 map reduce API 是绝对不合适的。只需设计一个真实的计算工作负载(例如计算素数);
于 2013-04-10T07:38:05.267 回答