Ethan is here!

by Administrator 27. April 2008 19:13

Ethan Connor Payne.  Born at 4:47PM CST on April 25th.  7lbs. 60z, 21" long.  We just brought him home.  Mom and baby are doing great.

Tags:

Almost babytime

by Administrator 24. April 2008 16:16

My wife is 1 week overdue now, so they are inducing her into labor around 7am tomorrow morning.  I will therefore be mostly off the grid for a brief while, though I'll post pictures when everything seems OK.

I have several semi-complete articles, so I should be posting quite a bit in May.

Tags:

Concurrent Unit Testing

by Administrator 17. April 2008 14:45

In the past I've occasionally announced something "coming soon" that never saw the light of day, and because of this I've greatly reduced the number of times that I mention any ideas that are still in the vaporware stage.  This time though I just wanted to get it out there.

I mentioned here that Unit Testing was a big chance to save developers time using concurrency.  I actually downloaded the NUnit source immediately after posting that and started looking at what it would take to get NUnit to run tests concurrently.  It's my current opinion, though I reserve the right to change my position later, that NUnit is an over engineered mess.  It uses some interesting combinations of patterns that ultimately makes an amazingly deep and hard to follow pipeline for test execution and result reporting.  The path for running a test suite goes something like this:

  1. Click "Run tests" button
  2. GUITestRunner
  3. ... passes to ThreadedTestRunnger (so the UI remains responsive)
  4. ... passes to ProxyTestRunner
  5. ... crosses a remoting boundary for some reason
  6. ... RemoteTestRunner
  7. ... passes to SimpleTestRunner
  8. Foreach unit test, execute, collect results...
  9. ... pass the results back across the remoting boundary to display in the GUI

I'm sure I'm missing at least one step in there.  The first trial of making SimpleTestRunner execute the tests in Parallel failed because there seems to be some bizarre hook in the test result capturing scheme that didn't like being threaded.  I will either track down this issue, create my own XTestRunner implementation, or blow an evening making my own unit test scheme that can run in parallel.  If I can then get TestDriven and NCover to hook into that, life would be good indeed.

Tags:

9,000 year old tree found

by Administrator 16. April 2008 19:38

I couldn't leave this one alone:

http://www.scienceblog.com/cms/world039s-oldest-living-tree-discovered-sweden-15937.html

The first thing I thought of when I saw this, sadly, was not "wow, what an awesome discovery!" but "Wait, isn't the world only 6,000 years old?".  As much as it would be a tragedy to harm these trees, I think we ought to take a core sample and count the rings on the trees.  What would surely follow is the sound of one thousand "thuds" as the creationists trip over themselves to refute the fact that the age of trees can be determined by counting rings.  Or, as my friend put it "The devil planted that tree to confuse us and test our faith."

Johnny Appleseed was the antichrist.

Tags:

possible dasBlog bug

by Administrator 16. April 2008 17:39

I had the most frustrating dasBlog issue over the past couple of days:

I suddenly found myself unable to post anything on my blog.  This coincidentally happened at the exact same time my hosting provider had me try a web.config change to alleviate some session/viewstate issues I was having.  I would try to make a post, get no errors, and be returned to the front page and see that my post was missing.  Referral logs were strangely missing, and the dasBlog event log was also strangely empty.  The only thing I could get a vague error message from was trying to post a comment.

Apparently, my "Anonymous Asp.Net user" had suddenly hit its disk-space quota.  I don't know if this quota was created recently or not.  It seems odd indeed that dasBlog would cruise along and never report an error when it's out of disk space.  I wonder if this is something dasBlog is doing or something that's happening because of the hosting environment?

Tags:

Klipschtastic Deep Zoom Sample

by Administrator 12. April 2008 05:06

http://www.klipschcorner.com/silverlight/DeepZoomTestPage.html

I have a multi scale image sample here, using code from Scott Hanslemann and others.   I had other photos to include, but no matter what machine I tried to build this on, the Deep Zoom Composer seemed to want to consume 100% CPU and 100% memory once I got up to 10 images or so.  The Palladium speakers are certainly beautiful, and with some print quality images you can count the coils on the transistors in the crossover.  These speakers are so beautiful.

Tags:

Five Places where Every Developer Could Benefit from Concurrency

by Administrator 9. April 2008 02:26

I have been told by more than one person that my Tree Concurrency articles were pretty, but vague and not applicable to what most developers are working on.  I had to consider this carefully.  I think it’s a natural way to express concurrency plus the dependency of one Task upon another.  Still, how many people would use such a scheme?

Long ago I wrote about this notion of Cage Builders (http://www.damonpayne.com/2005/05/10/CageBuilders.aspx) ; my favorite admonishment I heard constantly was “Don’t EVER use threads unless there’s no other way”.  No other way to what, I wonder?  I believe we are definitely past this ridiculous idea, or very nearly so anyway.  This is certainly a consideration for framework developers, and soon to be a common consideration of people developing line of business apps as well.  Concocted whilst I ate lunch today, here are five situations where any software developer could use the help of concurrency in their day to day work.

1 – Unit Testing

Real world projects could potentially have hundreds or thousands of unit tests in a solution.  If your team does not believe in unit tests, well, good for you, you won’t have this problem.  A good unit test strategy, especially for large projects with many people touching code, might be as follows:

1)      Check out code

2)      Run unit tests

3)      Make changes

4)      Create unit tests for your code

5)      Run unit tests to ensure nothing else has been broken by your code

6)      Get latest code that changed while you were working

7)      Run unit tests again

8)      Check in

 Running these tests before check ins and after check outs could become a non trivial chunk of your day.  Assuming one is following the best practice that each unit test must stand alone (set up any state needed for the test, run the test, destroy any created state) a group of Unit Tests is a great thing to be ran in parallel.  A suite of tests that takes a long time to run dis-incents developers from running them, and from adding to them. 

Unit test tools could benefit greatly from running in Parallel.  This would not only be useful on many-core machines.  Even on a single core machine (becoming rare as time goes on) you are very likely to have an application that contains a combination of business logic, disk access, computation logic, and so forth.  If Unit tests are being run in parallel, compute- or disk-bound tests can execute while tests requiring out of process calls block on network I/O.

If you are NOT following the practice of making unit tests stand alone, I happen to have published some libraries to manage in-order concurrent execution of tasks starting here http://www.damonpayne.com/ct.ashx?id=03c5e472-578d-4eee-ac28-5fca6434f617&url=http%3a%2f%2fwww.damonpayne.com%2fdefault.aspx%23a89abf6be-1354-40f4-a4cc-facaa28e6c4f.

 

2 – Batch Routines

While not as embarrassingly parallel as a Ray Tracer (http://msdn2.microsoft.com/en-us/magazine/cc163340.aspx) , many data import, data export, image generation, or data processing processes could take advantage of concurrency.  This may be the age of SOA, the Internet Service Bus, Ajax, distributed systems and “Real Time” in general, but a lot of business is still done and money is made using Batch processes.  One of CarSpot’s most useful features that keep customers around is our ability to send data and photos to AutoTrader.com, Cars.com, and so forth.  This is still mostly accomplished using Batch processing, FTP get and put, and a Zip file or two.   If you can make your batch processes go faster you can run them more often.  Running more often means the appearance of near real-time to your customers.

3 – Opening Files

Have you ever popped up an OpenFileDialog that allows the user to select multiple things to Display, Modify, or otherwise “use”?  You may ultimately be limited by the file system or whatever you are retrieving things from, but why not use concurrency so that things pop faster for the user?  This is especially true if you are opening multiple files at once and then computing something based on the file contents.  Using the Command pattern, which I am obviously obsessed with lately, works well for this.

4 – Application Startup

I don’t know how many times I’ve seen an ASP.Net application that caches a bunch of data on startup, and starts a logging engine, and starts an NHibernate or other ORM repository.  It’s easy to see from watching the Output window in the debugger that these things often involve out of process calls, JIT-ing, code generation, reflection emit, or other operations that take a little time.  Use concurrency and save a noticeable amount time when you are debugging hundreds of times per day.  Package all of these startup tasks as discrete units of work and get more done every day.

5 – Compiling Code

 In the beginning there was UNIX.  On UNIX, there was make.  Make makes your projects; make was a command line build tool.  As a build tool, one of make’s primary jobs was to determine when things were dirty and what needed to be built. You basically told make that these files over here (like *.cpp in such and such a directory) were processed with this tool over here (such as a C++ compiler) to produce such-and-such an output (like an executable or library).  If several object files from several directories needed to be combined into a shared object (DLL), make could determine the dependencies and build first what could be built.  Since make’s first job was dependency checking, this made a parallel-make easier to build and there were parallel and even distributed make implementations long ago.  Compiling hundreds of thousands of lines of C++ in 1998 was painful.

We need ms-build to use concurrency to build my solutions faster.   Ms-build already knows what projects depend on what other projects.  Make it so.

The Sadly Missing #6

Obviously there are more cases than what I’ve listed here.  I plan on sitting in my home theater with a nice chateauneuf-du-pape and thinking back over every application I’ve worked on in my consulting career to dig up some more ideas.  There is one thing that continually bothers me: this whole GUI thread thing.  To some degree, the Next Big Thing in concurrency has got to be something about solving this single-threaded painting issue.  I hope to attack this topic, but not until this winter unless a huge revelation comes to me out of nowhere.

Tags:

Managing Concurrency With Trees[4]

by Administrator 9. April 2008 01:32

Managing Concurrency With Trees[4]

Read the entire saga:

Managing Concurrency With Trees[0]

Managing Concurrency With Trees[1]

Managing Concurrency With Trees[2]

Managing Concurrency With Trees[3]

 

As I indicated at the end of the last article, I might come back to this topic.  I’m back.  Two things made me unable to put this topic down.  #1 was using Reflector and finding various code in Parallel.ForEach written around things like this:

private const int DEFAULT_LOOP_STRIDE = 8;

 

As near as I can read the code, the Parallel extensions don’t really get their swerve on until you’ve got quite a few more tasks than I’m using for examples here.  My uneducated suspicion is that this has to do with building up a queue of work for each thread and implementing the work stealing.

Recall from my last example I can even frustrate the TPL into executing quite a few things sequentially with that specific Enumerator implementation.  This is what I’d like to avoid.

I’ll definitely need to come up with some realistic examples with hundreds or thousands of little tasks, but for now I’ll try to see my original idea through.  But not with Parallel FX.  It’s time for Payneallel FX.

I made the comment to my muse  that I wondered how much it would take to make my own version of Parallel.ForEach: no fancy work stealing and  very specific to my problem.  The PFX team surely has very good reasons for doing what they are doing but I was frustrated at being unable to use my custom Enumerator.  I want to be able to write code like this:

Parallel.ForEach<IExecutable>(workTree, executeTask);// tree based, low # of tasks

… or like this …

            Parallel.ForEach<OddJob>(jobs, doJob); //List based, high # of tasks

…and have it work without hinting.   Thinking I was going to be blowing my whole weekend on this, I started thinking and typing.  Once I decided how to limit the number of threads created and re-use a thread rather than make a new thread for each task, it went much better than I expected.  Around 208 lines of code later, I had something that worked 100% the way I wanted it to!

There are three classes: a static class containing a static ForEach method, a WorkerPool class, and a Worker class.

Paralell.ForEach seems like a pretty good way to write this kind of code, so I imitated this interface.  Here’s the sample Main method:

            int exeCount = 0;

 

            Action<OddJob> doJob = delegate(OddJob j)

            {

                j.Execute();

                Interlocked.Increment(ref exeCount);

                Console.WriteLine("Executed " + exeCount);

            };

 

            List<OddJob> jobs = new List<OddJob>();

            for (int i = 0; i < 20; ++i)

            {

                jobs.Add(new OddJob());

            }

           

            Payneallel.ForEach<OddJob>(jobs, doJob);

This should look just like TPL code.  The actual implementation is presented in its entirety here with some basic description afterwards.

    public static class Payneallel

    {

        public static void ForEach<TSource>(IEnumerable<TSource> source, Action<TSource> body)

        {

            WorkerPool<TSource> pool = new WorkerPool<TSource>();

            foreach (TSource src in source)

            {

                Worker<TSource> worker = pool.GetWorker();

                worker.Arg = src;

                worker.Work = body;

                worker.Go();

            }

            pool.WaitAll();

        }

This couldn’t be simpler.  When the method is called a WorkerPool (thread pool) is created.  These are my threads, not threadpool threads, so I don’t need to worry about running long tasks on them.  We can choose to limit the number of threads created or not without needing to change this method or require anything of the client.  Worker<TSource>.Go() means “GO”, so work begins as soon as possible, this is where I had issues with my Tree<T> and the TPL.  Next, the WorkerPool implementation:

class WorkerPool<T>

        {

            public WorkerPool()

            {

                _workers = new List<Worker<T>>(Environment.ProcessorCount);

                for (int i = 0; i < Environment.ProcessorCount; ++i)

                {

                    Worker<T> worker = new Worker<T>("Payneallel " + i);

                    _workers.Add(worker);

                    worker.Done = new Action(WorkerDone);

                    worker.Go();

                }

                _workerDoneEvent = new ManualResetEvent(false);

            }

 

            private ManualResetEvent _workerDoneEvent;

            private static List<Worker<T>> _workers;

            private object _syncRoot = new object();

 

            /// <summary>

            ///

            /// </summary>

            public void WorkerDone()

            {

                lock (_syncRoot)

                {

                    _workerDoneEvent.Set();

                }

            }

 

            public Worker<T> GetWorker()

            {

                Worker<T> worker = GetFreeWorker();

                while (null == worker)

                {                   

                    _workerDoneEvent.WaitOne();

                    worker = GetFreeWorker();

                }

                _workerDoneEvent.Reset();

                return worker;

            }

 

            private Worker<T> GetFreeWorker()

            {

                foreach (Worker<T> w in _workers)

                {

                    if (!w.Busy)

                    {

                        Console.WriteLine("returning worker from pool");

                        return w;

                    }

                }

                return null;

            }

 

            public void WaitAll()

            {

                while (true)

                {

                    foreach(Worker<T> w in _workers)

                    {

                        w.Finish();

                    }

                    return;                

                }

            }

               

        }

The pool creates one Worker<T> for each physical CPU on the machine.  I’ve come back to wait handles as a means of making things work, but in this case I don’t mind because I’m limiting the number of threads I’m creating.  If Payneallel.ForEach calls GetWorker() but they are all busy, we block until a Worker is available.  WaitAll() makes sure the call to Payneallel.ForEach returns to the calling thread in a synchronous fashion.  The rest of the work is done in the Worker<T> class:

class Worker<T>

        {

            /// <summary>

            /// Set up initial state

            /// </summary>

            /// <param name="name"></param>

            public Worker(string name)

            {

                Name = name;

                Work = null;

                _active = true;

                Busy = false;

                _syncRoot = new object();

               

                _acceptingWorkEvent = new ManualResetEvent(true);

                _gotWorkEvent = new ManualResetEvent(false);

 

                ThreadStart ts = new ThreadStart(DoWork);

                Thread t = new Thread(ts);

                t.Name = Name;

                t.Start();

            }

 

            /// <summary>

            /// set _active to false so the thread will exit

            /// </summary>

            ~Worker()

            {

                _active = false;               

            }

 

            private ManualResetEvent _acceptingWorkEvent;

            private ManualResetEvent _gotWorkEvent;

 

            /// <summary>

            /// The name of the worker, used to Name the thread for easier debugging

            /// </summary>

            public string Name { get; set; }

 

            /// <summary>

            /// The worker is currently doing something

            /// </summary>

            public bool Busy { get; set; }

            private bool _active;

            private object _syncRoot;

 

            /// <summary>

            ///

            /// </summary>

            public Action<T> Work { get; set; }

 

            /// <summary>

            ///

            /// </summary>

            public T Arg { get; set; }

 

            /// <summary>

            /// Call back to the Pool to signify we're done

            /// </summary>

            public Action Done { get; set; }

 

            /// <summary>

            /// Block until done

            /// </summary>

            public void Finish()

            {

                _acceptingWorkEvent.WaitOne();

                _active = false;

            }

 

            /// <summary>

            /// Reset the wait flag so the thread running DoWork will start up again

            /// </summary>

            public void Go()

            {

                _gotWorkEvent.Set();

            }

 

            public void DoWork()

            {

                while (_active)

                {

                    _gotWorkEvent.WaitOne();//Wait for someone to call Go on us

                    if (null != Work && null != Arg) //make sure they set the callback action and the argument to the action

                    {

                        lock (_syncRoot)

                        {

                            Busy = true;

                            _acceptingWorkEvent.Reset();//Not accepting work now..

                        }

                        Work(Arg);//Do the action

                        Work = null;

                        Arg = default(T);

                        lock (_syncRoot)

                        {

                            Busy = false;

                            _acceptingWorkEvent.Set();//We are accepting work

                            _gotWorkEvent.Reset();//Don't have work

                            Done();//Call back to the pool in case someone is waiting on a free worker

                        }

                    }

                }

            }

        }

The Worker<T> has two wait handles to indicate working and available.  I believe the overhead in creating a thread is just enough that it makes sense to do things this way.  Creating a dozen threads is not a big deal (my x64 machine has around 1000 going most of the time) but I would probably avoid creating hundreds or thousands in order to do hundreds or thousands of Units of Work.  In the constructor for Worker<T>, the thread is created and started, however it isn’t doing anything until Go() is called, at which time the Action<T> is executed by the thread.  Note that I’m not taking any care whatsoever to think about thread local storage and the like.  I should probably look at this again to be sure the appropriate granularity of locking occurs.  The PFX team has got my head going 1000km/h and I’m just playing with petty alternate implementations of what they are doing.

I altered my TaskTreeEnumerator back to its original state before I had tweaked it beyond recognition trying to get PFX to play with me. Here is the new/original implementation for use with Paynellel:

        public override bool MoveNext()

        {

            lock (_syncRoot)

            {

                UpdateWork(_tree);

            }

 

            if (_runnableWork.Count > 0)

            {

                return true;

            }

            else

            {

                while (0 == _runnableWork.Count && !_tree.TrueForAll( new Predicate<IExecutable>(Executed) ))

                {

                    Thread.Sleep(200);

                    lock (_syncRoot)

                    {

                        UpdateWork(_tree);

                    }

                    if (_runnableWork.Count > 0)

                    {

                        return true;

                    }

                }

                //use this to block something until a task completes?

                Console.WriteLine("MoveNext->false");

                return false;

            }           

        }

 

        public override IExecutable Current

        {

            get

            {

                _current = _runnableWork.Dequeue();

                _current.Scheduled = true;               

                Console.WriteLine("Current Returning:" + base.Current.FriendlyClassName());

                return base.Current;

            }

        }

Because Paynellel.Foreach begins executing work as soon as it gets a single item, spinning inside MoveNext()  allows us to wait until prerequisite tasks have completed before moving on.

I just listened to the .NET Rocks episode today with Stephen Toub, program manager for the Parallel Computing Platform group at Microsoft.  He indicated there are some low-level synchronization primitives internal to the Task Parallel Library that they intend to make public in future CTPs of the Parallel Extensions framework.  He also indicated that to some degree, the December preview was “rough” internally, and was mainly meant to test the look of the API and get early client feedback.   I’m eagerly awaiting the next CTP.

Tags:

Who would pay for this?

by Administrator 8. April 2008 16:41

Someone in my fan club has too much time/money on their hands.  I took this screenshot just now:

 

Tags:

Missing in Action

by Administrator 7. April 2008 21:30

I sat down to continue some actual programming work today since it seemed support and manager-y type things had settled down.  Having gotten into WPF long before Silverlight, I found that to have a similar experience there are a lot of things I'm going to have to implement for the "CarSpot Silverlight Application Framework"

  • Commanding: I have seen references to people creating their own commanding frameworks for Silverlight 2.
  • Pages/Navigation: I wound up creating a Screen Stack for navigating from one Logical Page to another but without Pages and a Navigation Service I have to wire this all together myself. 
  • Security: It seems odd that Client Application Services was left out of Silverlight.  There are any number of ways to hack this in since the Silverlight control is sitting in the browser, but I was surprised to see that there was no "CurrentPrincipal" on the CurrentThread and so forth. I need security for my .aspx apps, why not for my Silverlight apps?  If one is building a line of busniess application, there are surely bits of information or actions that need to be hidden except for certain user roles.

Still, I'll take this over JavaScript any day.

Tags:

About the author

Damon Payne is a Microsoft MVP specializing in Smart Client solution architecture. 

INETA Community Speakers Program

Month List

Page List

flickr photostream