Reputation: 1223
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 IJobMaker
for example could harm performance because IProgressOverserver.ReportProgress
gets 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 the IProgressObserver.ReportProgress
method which resides in IJob
.
Upvotes: 2
Views: 1133
Reputation: 28981
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
#include <iostream>
using namespace std;
int main() {
float f = 0;
for(int i=0; i<100000-98; ++i)
{
f += 0.00001;
}
cout << f << endl;
}
So, if you have 100 jobs with 1000 steps each, you will have 1.0 result in 98 earlier than you could expect.
Upvotes: 0
Reputation: 500673
A couple of suggestions on the threading front:
0
...INT_MAX
.As far as designing the API, it shouldn't be too difficult to come up with something sensible. My general advice would be to not overengineer it.
Upvotes: 1