VS2010 Beta 2 is now available for download for MSN subscribers.
.NET Mutterings
Andy's observations as he continues to attempt to know all that is .NET...
Monday, October 19, 2009
Monday, October 05, 2009
Geometric Decomposition Screencast
I’ve posted a new screen cast on the Rock Solid Knowledge screen casts side that provides an example of how to partition a set of data for parallel processing.
The screen cast covers a simple way using Parallel.ForEach, and a more efficient version combining the use of Barrier.
You can checkout the screen cast and others here
Parallel utilities
Whilst working with .NET 4 parallel extensions I often find the need to extend the framework to assist me in various day to day tasks. I’ve finally got around to compiling a library of such extensions.
The extensions include the following
- Set Process Affinity, so I can see how my algorithm scales on a different number of cores. Will select non hyperthreaded cores first.
- Determine the number of Real cores, not including hyperthreading ones.
- A Range type that supports the partitioning of a range so that I can farm sub ranges out to different tasks
- A Sequence class for building non integer parallel loops or loops with steps other than 1
- Finally a simplified way to handle aggregated exceptions.
You can download the library from here
Its a Visual Studio 2010 project, containing the library and a unit test project which should provide enough insight to how the library works.
Im very keen to know what people think of the aggregate exception handling.
Friday, October 02, 2009
Are Singletons Evil ?
Finally got around to delivering a conference talk on this subject this week at Software Architecture Week, its a topic myself and Kevin Jones are constantly being asked. Of course a quick google reveals the answer there are numerous rants about this evil pattern. But like most things in life its not as simple as yes or no.
Our goal for this talk was to expose the areas were this pattern causes a developer a whole load of pain. In fact one member of the audience was experiencing such pain in his attempt to take legacy code base heavily utilising singletons and start to write unit tests.
So whilst the majority of the time was spent examining the consequences of using the singleton pattern we also took time to highlight that one or two singletons correctly positioned in your application could in fact enable unit testing, and coding to interface without having to refactor large areas of a legacy code base.
This talk took the format of a short geeky play, featuring two developers trying to wrestle with getting the job done and unit testing. You can download the script and accompanying code
So like all good consultants our answer to this question is “It Depends”
Friday, August 14, 2009
Fluent Parallel While
During devweek 2009 Oliver introduced me to Fluent Api's, I personally love programs that naturally read, after all programs are read far more often than written. This week a posting on the Parallel Extensions blog demonstrated how to achieve parallel while, since we only have Parallel.For and Parallel.ForEach
static void Main(string[] args)
{
ConcurrentQueue<int> queue = new ConcurrentQueue<int>();
for (int i = 0; i < 10; i++)
{
queue.Enqueue(i);
}
Action<ParallelLoopState> processQueue = (lps) =>
{
int item;
if (queue.TryDequeue(out item))
{
Console.WriteLine(" Thread Id = {0} Task Id = {1} : {2}", Thread.CurrentThread.ManagedThreadId, Task.Current.Id, item);
}
};
Func<bool> queueContainsItems = () => queue.IsEmpty == false;
ParallelUtil.While(new ParallelOptions(), queueContainsItems, processQueue);
}
I thought I’d combine both these ideas and produce what I would consider a more Fluent version
public static class ParallelUtil
{
private static IEnumerable<bool> Infinite()
{
while (true) yield return true;
}
private static ParallelOptions NoParallelOptions = new ParallelOptions();
public static void InParallelWhile(this Action<ParallelLoopState> action, Func<bool> condition, ParallelOptions options = null)
{
if (options == null) options = NoParallelOptions;
Parallel.ForEach(IterateForever(), options ,
(ignored, loopState) =>
{
if (!condition())
{
loopState.Stop();
}
else
{
action(loopState);
}
});
}
private static IEnumerable<bool> IterateForever()
{
while (true)
{
yield return true;
}
}
}
class Program
{
static void Main(string[] args)
{
ConcurrentQueue<int> queue = new ConcurrentQueue<int>();
for (int i = 0; i < 10; i++)
{
queue.Enqueue(i);
}
Action<ParallelLoopState> processQueue = (lps) =>
{
int item;
if (queue.TryDequeue(out item))
{
Console.WriteLine(" Thread Id = {0} Task Id = {1} : {2}", Thread.CurrentThread.ManagedThreadId, Task.Current.Id, item);
}
};
Func<bool> queueContainsItems = () => queue.IsEmpty == false;
processQueue.InParallelWhile(queueContainsItems);
}
}
}
The key difference is the first example you use the following line to process the queue in parallel
ParallelUtil.While(new ParallelOptions(), queueContainsItems, processQueue);
As opposed to the second version with a perhaps more fluent implementation
processQueue.InParallelWhile(queueContainsItems);
Friday, July 31, 2009
Linq for NHibernate
Its been a while coming, but there it is no possible to use LINQ against NHibernate..I think its a shame that MS didn’t get behind the Hibernate family when they first created LINQ as its a marriage made in heaven, combining a mature ORM with a language integrated query. Rather than spending all that time ( and still ) on trying to create their own ORM.
I’ve yet to try out the integration, but hopefully will be over the next few weeks…
Thursday, July 30, 2009
WARNING..Cancellation support may makes things go slow….
.NET 4 Tasks offers much better support for task cancellation, unlike QueueUserWorkItem tasks can be cancelled before commencing, and the Task library offers a standard way for running tasks to detect and report cancellation. I recently recorded a screencast that demonstrated the new Task API including the cancellation support. This blog post isn’t so much about the cancellation mechanics but some guidance on how best to use it if you don’t want to change the throughput of your task.
Below is some code that calculates pi, it is expecting to be run inside a task and is supporting the notion of cancellation.
private static double AbortableCalculatePi()
{
double pi = 1;
double multiplier = -1;
const int N_ITERATIONS = 500000000;
for (int nIter = 3; nIter < N_ITERATIONS; nIter += 2)
{
if (Task.Current.IsCancellationRequested)
{
Task.Current.AcknowledgeCancellation();
return 0.0;
}
pi += (1.0 / (double)nIter) * multiplier;
multiplier *= -1;
}
return pi * 4.0;
}
So all well and good until you benchmark it and compare it to the version with no cancellation support and it runs almost twice as slow. The reason being that the cost of detecting cancellation is high in relation to the work being done. The important aspect to cancellation is being able to respond in a meaningful time for the client, at present we are being way over aggressive in checking.
One option would be to only check every N iterations..
private static double BetterAbortableCalculatePi()
{
double pi = 1;
double multiplier = -1;
const int N_ITERATIONS = 500000000;
for (int nIter = 3; nIter < N_ITERATIONS; nIter += 2)
{
if ((nIter - 3) % 100000 == 0)
{
if (Task.Current.IsCancellationRequested)
{
Task.Current.AcknowledgeCancellation();
return 0.0;
}
}
pi += (1.0 / (double)nIter) * multiplier;
multiplier *= -1;
}
return pi * 4.0;
}
This took a third less time than the previous more aggressive version. However the if block’s effect on the pipeline and the additional maths is still an additional cost over the version that had no cancellation support.
So a third approach is called for this time refactoring the algorithm to use two loops instead of one, were the check for cancellation is done once per iteration of the outerloop, this results in little additional cost.
private static double OptimisedAbortableCalculatePi()
{
double pi = 1;
double multiplier = -1;
const int N_ITERATIONS = 500000000 / 2;
const int OUTER_ITERATIONS = 10000;
const int INNER_ITERATIONS = N_ITERATIONS / OUTER_ITERATIONS;
int i = 3;
for (int outerIndex = 0; outerIndex < OUTER_ITERATIONS; outerIndex++)
{
for (int nIter = 0; nIter < INNER_ITERATIONS; nIter++)
{
pi += (1.0 / i) * multiplier;
multiplier *= -1;
i += 2;
}
if (Task.Current.IsCancellationRequested)
{
Task.Current.AcknowledgeCancellation();
return 0.0;
}
}
return pi * 4.0;
}
Here are the timings are got from the various approaches
NoAbortableCalculatePi = 3.14159264958921 took 00:00:03.7357873
AbortableCalculatePi = 3.14159264958921 took 00:00:09.6137173
BetterAbortableCalculatePi = 3.14159264958921 took 00:00:06.3826212
OptimisedAbortableCalculatePi = 3.14159265758921 took 00:00:03.6883268
As the figures show there is virtually no difference between the first and last run, but a considerable difference when cancellation is inserted into the core of the computation.
So to sum up whilst cancellation support is good the frequency you check for could have an impact on the overall performance of your algorithm. Cancellation is something we want to support but in general users probably don’t need it so we need to strike the right balance between throughput and responding to cancellation in an appropriate timeframe.
.NET 4 Tasks and UI Programming
Just upload a new screencast covering how to marshal results from .NET 4 Tasks back on to the UI thread. One method is to continue to utilise the same API’s from previous versions of .NET thus utilising SynchronizationContext.Post, the Task based API offers an alternative and in some cases more elegant solution using the ContinueWith method.
Thursday, July 23, 2009
My First Silverlight 3 App
Had a brief rest from patterns and parallel stuff to have a quick play with Silverlight 3. I mainly wanted to see the out of browser aspect, as I think the idea of being able to build RIA that also run on the desktop is very compelling….
So what to build, I really like the iPhone weather app so I thought I’d have a go at reproducing it in Silverlight, below is a screen shot showing it running out of the browser.
I’m using isolated storage to store the list of weather centre’s of interest, a more typical line of business app would store app config on the web server/cloud and potentially locally to support true client roaming, but I’ll leave that for another day.
One thing to note is that the method for enabling Out Of Browser mode for you application is now different from pre-release versions of Silverlight 3, so there are many old blog posts that are unfortunately wrong now. The good news is now it is trivial, view the project properties, and under the Silverlight tab there is an option to enable the app to support out of browser. This then creates the OutOfBrowserSettings.xml file.
You can download the source via here or to just see the app in action click here. I’ll let you decide if its as cool as the iPhone….
Blog Archive
About Me
- Andy Clymer
- Im a freelance consultant for .NET based technology. My last real job, was at Cisco System were I was a lead architect for Cisco's identity solutions. I arrived at Cisco via aquisition and prior to that worked in small startups. The startup culture is what appeals to me, and thats why I finally left Cisco after seven years.....I now filll my time through a combination of consultancy and teaching for Developmentor...and working on insane startups that nobody with an ounce of sense would look twice at...