DCSIMG
January 2011 - Posts - Bnaya Eshet

Bnaya Eshet

Disclaimer

January 2011 - Posts

How to schedule Task on different thread priority?

How to schedule Task on different thread priority?

 

Parallel, Task, Scheduler, Thread, Priority, C#, .net

.NET 4 brought as the Task Parallel Library (TPL)

which is great improvement over the old threading

techniques, both in terms of API and performance.

the TPL APIs is elegant and clear, but intentionally

the TPL team didn't add API (out of the box) for scheduling

thread under different priorities.

 

this post deal discuss how to create custom TPL scheduler that schedule the

work units under different thread priorities.

 

the code sample for this post can be download from here.

 

TPL APIs

most of the TPL APIs expose overload with scheduler parameter.

out of the box TPL is having 2 schedulers:

  • Default scheduler.
  • synchronization context (Dispatcher) scheduler (for synchronizing work back into the
    synchronization context like UI thread), see TaskScheduler.FromCurrentSynchronizationContext().

 

How can we change the behavior of the scheduler?

building custom scheduler involve with inheritance of TaskScheduler.

in our sample we will use BlockingCollection<Task> for having

thread safe consumer producer pattern which will consume work

under custom thread that run on specific priority.

 

Overriding TaskScheduler

TaskScheduler is having small amount of virtual and abstract methods:

Code Snippet
  1. public class TaskScheduler
  2. {
  3.     public virtual int MaximumConcurrencyLevel { get; }
  4.     protected internal abstract void QueueTask(Task task);
  5.     protected internal virtual bool TryDequeue(Task task);
  6.     protected abstract bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued);
  7.     protected abstract IEnumerable<Task> GetScheduledTasks();
  8. }

the most important overrides is QueueTask which get

the task and responsible to schedule it execution.

in our implementation it enqueue the task into the producer consumer collection

and make sure that the worker threads is running.

Code Snippet
  1. protected override void QueueTask(Task task)
  2. {
  3.     _collection.Add (task);
  4.  
  5.     if (!_workerThread[0].IsValueCreated)
  6.     {
  7.         for (int i = 0; i < _maximumConcurrencyLevel; i++)
  8.         {
  9.             _workerThread[i].Value.Start();
  10.         }
  11.     }
  12. }

the actual task execution is done by consuming tasks (under the worker thread)

and call base.TryExecuteTask(task), as shown in the following code snippet:

Code Snippet
  1. foreach (Task task in _collection.GetConsumingEnumerable())
  2. {
  3.     base.TryExecuteTask(task);
  4. }

 

TPL APIs

the custom scheduler can be inject into the TPL APIs as shown in the following snippets:

Code Snippet
  1. Task.Factory.StartNew(..., cancelSouce.Token, TaskCreationOptions.None, scheduler);
  2. var options = new ParallelOptions { TaskScheduler = scheduler};
  3. Parallel.For(1, 10, options, i => ...);

 

The sample

the sample compare execution of tasks with default and custom scheduler.

you may notice that thread that run under custom scheduler is also having thread name.

the output of the sample is look as follow:

Parallel, Task, Scheduler, Thread, Priority, C#, .net

Summary

the parallel team intentionally didn't include priority scheduler for a good reason,

and most common execution should be avoid using such scheduler.

however there may be some special occasions which it might make sense

to use such scheduler, like:

  • execution of debug level logger write under low priority in order to prevent it from compete upon CPU resources.
  • execution test under controlled environment might take advantage of custom test scheduler.

the code sample for this post can be download from here.

 

kick it on DotNetKicks.com
Digg This

Enum.HasFlag: good or bad?

Enum.HasFlag: good or bad?

.NET 4 give us nice elegant way of checking whether [Flags] enums

contain a value.

 

assuming that we have the following enum:

Code Snippet
  1. public enum MyEnum
  2. {
  3.     None = 0,
  4.     A = 1,
  5.     B = 2,
  6.     C = 4,
  7.     D = 8
  8. }

we can use the bitwise for checking whether instantiation of

the enum contain a value, as shown in the next snippet:

Code Snippet
  1. var options = MyEnum.A | MyEnum.B;
  2. if ((options & MyEnum.A) == MyEnum.A)
  3. {
  4.     // Do something
  5. }

.NET 4 come with elegant syntax which look like the following:

Code Snippet
  1. var options = MyEnum.A | MyEnum.B;
  2. if (options.HasFlag (MyEnum.A))
  3. {
  4.     // Do something
  5. }

whether it good or bad to use the new syntax we will discover soon,

anyway it is surely not ugly.

 

What's the problem with this syntax?

the problem with the syntax is that it is not syntactic sugar (as we might thought).

as elegant and convenient it is, it is hiding reflection operations (GetType()).

using this syntax under intensive iteration you may lead to performance hit.

 

the following output show the effect of having Enum.HasFlag inside intensive iteration:

Enum, HasFlags, flags, C#, .NET

the full code for this test can be find at:

http://codepaste.net/9jtz98

 

basically it compare

Code Snippet
  1. for (int i = 0; i < 1000000; i++)
  2. {
  3.     var hasOption = (options & MyEnum.A) == MyEnum.A;
  4.     hasFlag = hasFlag && hasOption;
  5. }

with

Code Snippet
  1. for (int i = 0; i < 1000000; i++)
  2. {
  3.     var hasOption = options.HasFlag(MyEnum.A);
  4.     hasFlag = hasFlag && hasOption;
  5. }

 

Summary

Enum.HasFlag is definitely slower than the bitwise comparison, but it is cleaner

and more readable.

therefore I may argue that it is OK to use it unless it is under intensive iteration.

 

point of interest

the implementation of Enum.HasFlag is:

Code Snippet
  1. public bool HasFlag(Enum flag)
  2. {
  3.     if (!base.GetType().IsEquivalentTo(flag.GetType()))
  4.     {
  5.         throw new ArgumentException(Environment.GetResourceString("Argument_EnumTypeDoesNotMatch", new object[] { flag.GetType(), base.GetType() }));
  6.     }
  7.     ulong num = ToUInt64(flag.GetValue());
  8.     return ((ToUInt64(this.GetValue()) & num) == num);
  9. }

 

kick it on DotNetKicks.com
Digg This

SDP (SELA annual conference) - Parallel Programming

SDP (SELA annual conference) - Parallel Programming

clip_image002

SELA Group is having it's annual conference at 13-16 March 2011,

 

In the conference I’m going to have one-day tutorial (along with Yaniv Rodenski) about Parallel Programming.

In this one-day tutorial you will cover how to gain real benefits from parallelizing your applications with .NET 4.0. We'll discuss parallel programming paradigms and concepts, APIs, concurrency profiling, parallel patterns and anti-patterns. Among the topics: implicit and explicit parallelism, synchronization, concurrent collections, partitioning, Reactive Extensions, and the future C# 5.0 parallelism.

 

If you happened to be in Israel you may consider to join our tutorial at the March 14.

Digg This

How to find which core your thread is scheduled on?

How to find which core your thread is scheduled on?

this post is short and quit simple,

it deal with technique of finding out which core attached to the current thread.

 

in general finding the core is a matter of diagnostic, it may give some insights like

whether we are using the CPU cache line in optimal way.

the simplest way (and a very recommended one) is to profile your application

using the Visual Studio Concurrent Profiler (which available on VS 2010 ultimate).

Parallel, core, Tpl, Task, Task.Factory, CPU

in case that you have the need of finding the attached core at runtime from C# code,

you can PInvoke GetCurrentProcessorNumber as shown in the following snippet:

Code Snippet
  1. [DllImport("Kernel32.dll"), SuppressUnmanagedCodeSecurity]
  2. public static extern int GetCurrentProcessorNumber();
  3.  
  4. static void Main(string[] args)
  5. {
  6.     Parallel.For (0, 10 , state => Console.WriteLine("Thread Id = {0}, CoreId = {1}",
  7.         Thread.CurrentThread.ManagedThreadId,
  8.         GetCurrentProcessorNumber()));
  9.     Console.ReadKey();
  10. }

also available at: http://codepaste.net/un731f

 

Summary

do not assume that single thread will be schedule on single core,

thread may switch cores after context switching.

this technique is also limited for Windows Vista and above.

 

Credits

http://msdn.microsoft.com/en-us/library/ms683181(VS.85).aspx

 

kick it on DotNetKicks.com
Digg This