|
Boost : |
From: áÎÄÒÅÊ óÅÍÁÛÅ× (andysem_at_[hidden])
Date: 2007-09-21 15:14:41
> > Why is it that bad? This is safier since there is no opportunity to get an
> > error on the threading primitive construction, it doesn't use system
> > resources like kernel objects and it solves the fundamental problems of
> > creating and destroying those threading primitives in run time. And it will
> > be run only once after all, so performance is not an issue.
>
> I think that performance *is* an issue, even though this will only be run once
> per thread.
>
> A check/sleep polling loop is a bad idea, as it consumes CPU time that could
> be spent actually running the once routine (or another thread that doesn't
> need to wait). By waiting on an OS primitive, the OS can take the thread out
> of the schedule until the primitive is ready to be acquired.
That's true, but consider that:
a) sleeping happens only on contention
b) the contention is unlikely to happen unless the once routine takes a long time.
Besides I'd like to note that spinning in a sleeping loop a couple of rounds may be equivalent (in CPU cycles wasted) to constructing the synchronization object, locking/unlocking and destroying it. These are all calls to kernel and are all expensive. Having said that sleeping may never ever happen, the dance with the synchronization object looks even less performant to me in majority of cases.
> Not only that, but a check/sleep loop forces a latency of at least the
> specified sleep time on the waiting thread. If the initialization being waited
> for only takes a few microseconds (or less --- if it's just a simple
> initialization it might take only a few nanoseconds), then waiting a whole
> millisecond is an unnecessary delay.
With all due respect, I doubt that. It all comes down to the scheduler resolution. Blocking on a mutex doesn't mean you'll wake right when it's unlocked. You may end up with the same latency as sleeping for a tiny period.
> POSIX provides pthread_once. We should use it. The Windows Vista functions
> look to supply a similar facility, and do at least allow the passing of a
> parameter to the routine without using TSS.
I strongly disagree. If there's something out there it doesn't mean we ought to use it. Especially if it doesn't suit us. I agree with Tobias on his point that it is a really bad idea to propagate exceptions through OS API like pthread_once or InitOnceExecuteOnce. This makes such API of little worth for C++.
Finally, I'd like to underline it once more. Out of my experience (and as I see in other postings, not only my) the expences on the first call_once execution are expendable. The main requirements are reliability (in the way it won't fail for some reason unless your code fails) and minimal resource usage after the first execution (this means especially CPU, memory and system resources like kernel objects). Actually, I haven't seen the case being otherwise.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk