January 2011 - Posts
How to schedule Task on different thread priority?
.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
- public class TaskScheduler
- {
- public virtual int MaximumConcurrencyLevel { get; }
- protected internal abstract void QueueTask(Task task);
- protected internal virtual bool TryDequeue(Task task);
- protected abstract bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued);
- protected abstract IEnumerable<Task> GetScheduledTasks();
- }
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
- protected override void QueueTask(Task task)
- {
- _collection.Add (task);
-
- if (!_workerThread[0].IsValueCreated)
- {
- for (int i = 0; i < _maximumConcurrencyLevel; i++)
- {
- _workerThread[i].Value.Start();
- }
- }
- }
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
- foreach (Task task in _collection.GetConsumingEnumerable())
- {
- base.TryExecuteTask(task);
- }
TPL APIs
the custom scheduler can be inject into the TPL APIs as shown in the following snippets:
Code Snippet
- Task.Factory.StartNew(..., cancelSouce.Token, TaskCreationOptions.None, scheduler);
- var options = new ParallelOptions { TaskScheduler = scheduler};
- 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:
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.
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
- public enum MyEnum
- {
- None = 0,
- A = 1,
- B = 2,
- C = 4,
- D = 8
- }
we can use the bitwise for checking whether instantiation of
the enum contain a value, as shown in the next snippet:
Code Snippet
- var options = MyEnum.A | MyEnum.B;
- if ((options & MyEnum.A) == MyEnum.A)
- {
- // Do something
- }
.NET 4 come with elegant syntax which look like the following:
Code Snippet
- var options = MyEnum.A | MyEnum.B;
- if (options.HasFlag (MyEnum.A))
- {
- // Do something
- }
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:

the full code for this test can be find at:
http://codepaste.net/9jtz98
basically it compare
Code Snippet
- for (int i = 0; i < 1000000; i++)
- {
- var hasOption = (options & MyEnum.A) == MyEnum.A;
- hasFlag = hasFlag && hasOption;
- }
with
Code Snippet
- for (int i = 0; i < 1000000; i++)
- {
- var hasOption = options.HasFlag(MyEnum.A);
- hasFlag = hasFlag && hasOption;
- }
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
- public bool HasFlag(Enum flag)
- {
- if (!base.GetType().IsEquivalentTo(flag.GetType()))
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_EnumTypeDoesNotMatch", new object[] { flag.GetType(), base.GetType() }));
- }
- ulong num = ToUInt64(flag.GetValue());
- return ((ToUInt64(this.GetValue()) & num) == num);
- }
SDP (SELA annual conference) - Parallel Programming

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.
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).
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
- [DllImport("Kernel32.dll"), SuppressUnmanagedCodeSecurity]
- public static extern int GetCurrentProcessorNumber();
-
- static void Main(string[] args)
- {
- Parallel.For (0, 10 , state => Console.WriteLine("Thread Id = {0}, CoreId = {1}",
- Thread.CurrentThread.ManagedThreadId,
- GetCurrentProcessorNumber()));
- Console.ReadKey();
- }
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