Tuesday, January 12, 2010

Choose : Parallel or not in .NET 4.0 beta 2; Part 1

This is a little sample to choose parallel or not. It is used LINQ to object.

Example of source code:


DateTime start = DateTime.MinValue;
DateTime stop = DateTime.MinValue;
TimeSpan seleisih;
Console.WriteLine("Sequential");

IEnumerable<int> cobaAss = Enumerable.Range(0, 30000000);
var hh = from x in cobaAss
         where x % 3 == 0
         select Math.Sqrt(x);
start = DateTime.Now;
foreach (var item in hh)
{
    double x = item * 1.5;
}
stop = DateTime.Now;
seleisih = stop - start;

Console.WriteLine("Start : {0}", start);
Console.WriteLine("Stop : {0}", stop);
Console.WriteLine("Selisih (tick) : {0}", seleisih.Ticks);

// --

Console.WriteLine("Parallel");

cobaAss = Enumerable.Range(0, 30000000);
hh = from x in cobaAss.AsParallel()
     where x % 3 == 0
     select Math.Sqrt(x);
start = DateTime.Now;
//Parallel.ForEach<double>(hh, (item) => { });
foreach (var item in hh)
{
    double x = item * 1.5;
}
stop = DateTime.Now;
seleisih = stop - start;

Console.WriteLine("Start : {0}", start);
Console.WriteLine("Stop : {0}", stop);
Console.WriteLine("Selisih (tick) : {0}", seleisih.Ticks);

Console.WriteLine("Parallel Doit manually");

var cobaAss1 = Enumerable.Range(0, 10000000);
var cobaAss2 = Enumerable.Range(10000000, 10000000);
var cobaAss3 = Enumerable.Range(20000000, 10000000);

var hh1 = from x in cobaAss
          where x % 3 == 0
          select Math.Sqrt(x);
var hh2 = from x in cobaAss
          where x % 3 == 0
          select Math.Sqrt(x);
var hh3 = from x in cobaAss
          where x % 3 == 0
          select Math.Sqrt(x);
start = DateTime.Now;
Parallel.Invoke(
    () =>
    {
        foreach (var item in hh1)
        {
            double x = item * 1.5;
        }
    },
    () =>
    {
        foreach (var item in hh2)
        {
            double x = item * 1.5;
        }
    },
    () =>
    {
        foreach (var item in hh3)
        {
            double x = item * 1.5;
        }
    });
stop = DateTime.Now;
seleisih = stop - start;

Console.WriteLine("Start : {0}", start);
Console.WriteLine("Stop : {0}", stop);
Console.WriteLine("Selisih (tick) : {0}", seleisih.Ticks);

Console.ReadLine();


I use console project to use it. You can try your own test

Below is the result:

test_parallel

This is strange since sequential is faster than parallel using AsParallel() or manually to do in parallel.

Summary: Parallelism is not always fasten the query

Sunday, January 10, 2010

Forcing parallelism in .NET 4 b2

Concurrent and parallel programming is really hard to develop. In the old days like .NET 3.x, 2.0 or older, developer can obtain parallel by creating a new thread, maintain their own thread manually; that can harm system performance and execution when not managed carefully.

The past approach (.NET 2.x-3.x)

public static void DoSomething()
{
      // do something hard and time consuming like counting with loop
      while(true)
      {
             int x = 3 + 5;
       }
}

public static void Run()
{
      Thread t = new Thread(new ThreadStart(DoSomething));
      t.Start();
      t.Join();
      // do whatever
}

In the .NET 4.0 (right now I use beta 2), It is easier to develop by using Invoke method from Parallel class
public static void Run()
{
      Parallel.Invoke(()=>{ DoSomething(); });
}

Code above will pause main thread and run all code inside Invoke until all running thread terminated. This method deliver more safety than manual ones.

Developer can easily set processor affinity for specific thread by assigning them into the methods. Processor affinity is a bit flags. The documentation is available on microsoft MSDN on class Process with property ProcessorAffinity.

For example, the thread will be executed on second processor, set affinity by

public static void Run()
{
      Parallel.Invoke(()=>{
              Process.GetCurrentProcess().ProcessorAffinity = (IntPtr)2;
              DoSomething(); }
      );
}

In task manager. the process will make second processor runs high.

cpu_sibuk