Parallell computing in .net 4

by Christer 29. November 2009 18:12

There are some new neat feature for doing parallel computing and taking advantage of multiple cores in .net 4, and i thought id check some of them out.

First i need a testsetup, and i thought id just use something that use up a lot of cpu and cooked together a simple console app that counts the number of primes in a specified range.

static void Main(string[] args)
{
    Console.WriteLine("Starting..");
    DateTime d = DateTime.Now;

    var c = Enumerable.Range(1, 100000)
        .Where(i => IsPrime(i))
        .Count();

    TimeSpan elapsed = DateTime.Now - d;

    Console.WriteLine(string.Format("Done!. Found {0} primes in {1} ms\n\nPress enter to exit",c, elapsed.TotalMilliseconds));

    Console.ReadLine();
}

and the IsPrime function:

static bool IsPrime(int val)
{
    for (int i = 2; i <= val / 2; i++)
        if (val % i == 0)
            return false;

    return true;
}

The primecheck isnt built for speed, its built for hogging up cpu and giving me a result that i can verify that its correct (Though some might complain that it will treat 1 as a prime, but hey! Im not a mathematician, 1 is a perfectly good prime in my world =)

The initial testrun gives:

Starting..
Done!. Found 9593 primes in 1201,0687 ms 

Press enter to exit

After a bunch of more runs it seems to keep around 1150ms to 1250ms, so about 1200 ms seems about right.

good, we have our baseline, but thats not very interesting so how do we get this to run in parallell? Well, it isnt very hard. All thats needed is to add .AsParallel() to the initial loop like this:

var c = Enumerable.Range(1, 100000)
    .AsParallel()
    .Where(i => IsPrime(i))
    .Count();

Ok, that was easy enough. but does it do anything? First run gave:

Starting..
Done!. Found 9593 primes in 697,0399 ms

Press enter to exit

And after a few more tests it seems to land on about 700ms \o/ so a 42% performance increase on my dual core cpu. cool! I thought id try a final check aswell, and cranked it up to calculate from the range of 1 million numbers instead of a hundred thousand so i get some time to check the cpu usage, and it looks like this when running without AsParallell:

SingleThread

And with AsParallell:

MultiThread

 

So indeed its using upp both cores now after i helped it a bit \o/. Also you can control it a bit more by specifying .WithDegreeOfParallelism(xxx) where xxx is “the maximum number of concurrently executing tasks that will be used to process the query” (from the intellisense =). That can be handy when for ex downloading stuff from the internet. More than one thread could be handy, but spinning up hundreds of threads probably wont increase the speed alot and will most likely hog up all your bandwidth.

Luca Bolognese talks about this in his awesome session Future Directions for C# and Visual Basicaswell, so check that out for a bit more info. He also shows a a new way of handeling async operations that might be added in the future (after .net 4).

Tags: , , ,

Development

blog comments powered by Disqus

Creative Commons License
This work is licensed under a Creative Commons Attribution-Share Alike 2.5 Sweden License.


Welcome to the Dropit blog!

Here we, the people that work at Dropit, will write about stuff that interests us. For example web development, especially with .NET and EPiServer - but we'll also talk about other techniques that interest us, marketing on the web, social phenomenons, pop culture, games and software development in general.