网上有人说下面的C#代码不能转换成一些Parallel.for(多核系统)是这样吗?如果是,是否有更好的方法来进一步优化它。谢谢
for (int i = 0; i < 4; i++)
{
var tmp = i;
tasks[i] = Task.Factory.StartNew(() => Console.WriteLine(tmp));
}
网上有人说下面的C#代码不能转换成一些Parallel.for(多核系统)是这样吗?如果是,是否有更好的方法来进一步优化它。谢谢
for (int i = 0; i < 4; i++)
{
var tmp = i;
tasks[i] = Task.Factory.StartNew(() => Console.WriteLine(tmp));
}
好吧,你最后没有 a Tast.WaitAll(tasks)
,这Parallel.For
对你有用,所以你并没有完全做Parallel.For
正在做的事情(除非你没有把代码放在你的问题中。如果是这样,那么下一行就是你的代码看起来像一个 Parallel.For 循环)
Parallel.For(0,4, (i) => Console.WriteLine(i));
除此之外,我不明白为什么不能将其转换为 Parallel.For。该人给出了无法转换它的什么原因?
因为我们没有外部循环代码,所以我在这里暗中尝试。如果您只是测量总体平均运行时间,则不需要存储任务,您可以使用类似这样的方法来测量串行和并行版本:
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 定律加速。
首先,关于您报告的错误:
未处理的异常:System.AggregateException:发生了一个或多个错误。System.ArgumentExcpetion:任务数组包含至少一个空元素参数名称:Tasks
错误很明显,它是由您的Task.WaitAll
调用引发的 - 它表示您的tasks
数组中的任务槽之一为空。
其次,衡量性能Console.WriteLine
不好有两个原因:
Console.WriteLine
是同步的——这意味着所有任务都将开始,然后立即同步——在这种情况下,使用 map reduce API 是绝对不合适的。只需设计一个真实的计算工作负载(例如计算素数);