I have a library with an IJobMaker entity that creates a certain amount of IJob objects to be run on threads of their own managed by the user.
To track each IJob‘s progress I implement the observer pattern with an IProgressObserver within every job. The difficulty arises when I wish to report on OVERALL progress.
The ideal for me would be to have IProgressOverserver.ReportProgress(float jobProgress, float overallProgress that reports both job and overall progress.IJobMaker can be aware of each job’s portion of the overall work and somehow gather everyone’s reports.
Two main questions arise:
-
Synchronization mechanism? Keeping a mutex inside
IJobMakerfor example could harm performance becauseIProgressOverserver.ReportProgressgets called a lot and a mutex could incur a context switch and what not. InterlockedIncrement looks like a good option but since there’s no such function for floating point, I would be forced to report progress by integer increments. (I’d like to stay away from c++0x features or Boost) -
Design pattern?
IJob‘s progress is reported from within its deepest algorithms. I need every such a report to both communicate with a central entity for overall progress calculation and call theIProgressObserver.ReportProgressmethod which resides inIJob.
First of all, it’s quite bad practice to use floats in such cases. Use an integer.
There is another suggestion. You can use segmentation – synchronise only few threads by one mutex/atomic (one segment). And then collect total among all segments.
Also, there is good place to start looking around highly parallel algorithms: http://www.1024cores.net/home/lock-free-algorithms
UDPATE
There is example of problems with the float
So, if you have 100 jobs with 1000 steps each, you will have 1.0 result in 98 earlier than you could expect.