Back to Basic: Using a System.Threading.Interlocked is a great idea
I just saw some code which actually takes a lock to do a simple set operation. This is bad because taking locks are expensive and there is an easy alternative. The System.Threading.Interlocked class and its members can get the same job done and much faster.
I wrote the following two methods which increments a variable a million times. The first method does that by taking a lock and the other uses the Interlocked.Increment API.
static int IncrementorLock()
{
int val = 0;
object lockObject = new object();
for (int i = 0; i < 1000000; ++i)
{
lock (lockObject)
{
val++;
}
}
return val;
}
static int IncrementorInterlocked()
{
int val = 0;
for (int i = 0; i < 1000000; ++i)
{
System.Threading.Interlocked.Increment(ref val);
}
return val;
}
I then used the Visual Studio Team System Profiler (instrumented profiling) and got the following performance data.
Function Name | Elapsed Inclusive Time | Application Inclusive Time |
LockedIncrement.Program.IncrementorInterlocked() | 1,363.45 | 134.43 |
LockedIncrement.Program.IncrementorLock() | 4,374.23 | 388.69 |
Even though this is a micro benchmark and uses a completely skewed scenario, it still drives the simple point that using the interlocked class is way faster.
The reason the interlocked version is faster is because instead of using .NET locks it directly calls Win32 apis like InterlockedIncrement which ensures atomic updation to variables at the OS scheduler level.
These Interlocked APIs complete depend on the support of the underlying OS. This is the reason you'd see that all the APIs are not available uniformly across all versions of .NET (e.g. there is no uniform coverage over WinCE and Xbox). While implementing these for the Nokia platform (S60) we are hitting some scenarios where there is no corresponding OS API.
Comments
Anonymous
August 25, 2008
Thank you very much for this tip! I had not heard of this Interlocked method of doing a thread lock, and it seems much more straightforward to use. I have an application where I need to do a threading lock, and happened across your article. Based on your tip, I'll use this method instead of the old lock(object) style. Thanks for expanding my knowledge of this.Anonymous
August 25, 2008
you are welcome :)