Reputation: 29
Someone on the net said the following C# code cannot be converted to some Parallel.for (for multi-core system) is that correct? If yes, is there a better way to optimize it further. thanks
for (int i = 0; i < 4; i++)
{
var tmp = i;
tasks[i] = Task.Factory.StartNew(() => Console.WriteLine(tmp));
}
Upvotes: 0
Views: 332
Reputation: 16796
First, about the error you reported:
Unhandled Exception: System.AggregateException: One or more erroros occured. System.ArgumentExcpetion: The tasks array inclue at least one null element paraemeter name: Tasks
The error is pretty clear, it is raised by your Task.WaitAll
call - it says that one of the task slots in your tasks
array is null.
Second, measuring performance on Console.WriteLine
is bad for two reasons:
Console.WriteLine
is synchronized - meaning that all the tasks will begin and then immediately synchronize - it is the case for which using a map reduce API is absolutely inappropriate. Just design a real computing workload instead (e.g. calculating prime numbers);Upvotes: 0
Reputation: 3455
Since we don't have the outer loop code I am taking a stab in the dark here. If you are just measuring overall average runtime you don't need to store the tasks, you could use something like this to measure serial and parallel versions:
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);
This may not be a great test for measuring speedup since the workload is so light. You could try calling a function with more overhead or something like Thread.Sleep
to imitate more work. Also see my answer at This StackOverflow Question for how to measure Amdahl's Law speedup in C#.
Upvotes: 0
Reputation: 19175
Well, you don't have a Tast.WaitAll(tasks)
at the end, which Parallel.For
would do for you, so you are not quite doing what Parallel.For
is doing (unless you have not put that code in your question. If so then the next line is what your code would look like as a Parallel.For loop)
Parallel.For(0,4, (i) => Console.WriteLine(i));
Other than that, I don't see why you can't convert it to Parallel.For. What reason did the person give for not being able to convert it?
Upvotes: 1