|
Boost : |
From: Dan Nuffer (dnuffer_at_[hidden])
Date: 2001-03-15 12:12:04
williamkempf_at_[hidden] wrote:
>
> Thanks very much for your interest and comments.
Your welcome. I also didn't mention it initially, because I was too
eager to write down my suggestions before I forgot it all, but I think
you've done a great job getting everything to its current state. Thanks
for all your work.
> Phase 1. I expect to add them in Phase 3. The introduction in the
> documentation will help you to understand why, though this type was
> not specifically mentioned.
>
Okay, I just wanted to make sure that they weren't being overlooked or
ignored :)
>
> > The example you provided for the semaphore is more appropriate for
> a mutex.
> > I think that a bounded buffer would show the semaphore concept
> better.
>
> I very much agree that the example is contrived and does not show the
> benefits of the semaphore at all. I don't think a bounded buffer is
> a better example, however, as that example is better suited for (and
> given in the documentation for) a condition. I'll think about a
> better example for this one.
>
True. I suggested the bounded buffer because it is the example used in
my college textbook as an example use of semaphores.
>
> > I think you should move a lot of the simple 1-3 line functions from
> the .cpp
> > files into the .hpp files such as:
> >
> > semaphore::semaphore(unsigned count, unsigned max)
> > : pimpl(new impl(count, max))
> > {
> > }
> >
> > semaphore::~semaphore()
> > {
> > delete pimpl;
> > }
> >
> > bool semaphore::up(unsigned count, unsigned* prev)
> > {
> > return pimpl->up(count, prev);
> > }
> >
> > bool semaphore::down(unsigned milliseconds)
> > {
> > return pimpl->down(milliseconds);
> > }
>
> This would require the "impl" class to be visable to client code,
> which is exactly the opposite of the purpose. The implementation is
> supposed to be hidden completely from client code. Specifically, I
> don't want client code to include files such as Windows.h, even
> indirectly, since this will polute the namespace and slow
> compilation. All refactoring that will place these functions in the
> header and yet insure my goal of hiding the implementation will
> result in no speed increase from inline optimizations.
>
> > Also, I wonder if the advantages of the pimpl idiom are greater
> than the
> > disadvantages? I definitely think it will cause a performance hit.
> > Everytime you lock or unlock a mutex, you've got to dereference the
> pimpl
> > pointer. And for every primitive you create you've got to call new
> and then
> > delete when it goes away. Is there any advantage other than a
> slightly
> > faster compile?
>
> It's more than "slightly" on many platforms, Windows being one of
> them. Further, I don't want to pollute the namespace. The only
> overhead occurs within construction/destruction, which are not likely
> to occur in time critical locations and so shouldn't be noticed in
> most applications.
>
AFAIK, there is no compiler that can inline functions that haven't been
included in a header file. That means, when I write some code that uses
the library, when I create a mutex or other primitive, it will have to
call new to allocate the pimpl, that much dynamic allocation is
unacceptable for some applications. Then when I create a lock, it will
then have to first call the lock constructor (can be inlined),
dereference a pointer to the mutex, and then make a function call (not
inlined) to the mutex's do_lock function, which will then dereference
the pimpl pointer and call the real do_lock function (can be inlined
into functions that call it in the .cpp), which then has to call the
os/library to do the lock. This seems like a lot of unnecesary
overhead. I think performance is very important. I recently
benchmarked an application I had worked on that used the Xerces XML
parsing library. The biggest time consuming functions were in the
library: pthread_mutex_lock and pthread_mutex_unlock. After that, there
were two other layers that were almost equal in time consumption: the
platform abstraction function XMLPlatformUtils::lockMutex(void* const
mtxHandle), which was defined in the .cpp and thus not inlined. Next
was void XMLMutex::lock() which was the same thing. Now if the Xerces
library had written those two functions in the header files, they
would've been inlined and the app would've gained at least 15% speed
improvement. The extra layers effectively doubled the time spent
locking/unlocking mutexes.
I can understand your not wanting to include windows.h in the header
file, but I think you're overstating the negative impact. If you're
writing a program to run on windows, odds are you've already included
windows.h and then there's pre-compiled headers with MSVC. For pthreads
platforms, including pthreads.h is trivial.
Maybe you could take the approach of using a .ipp file, where if the
user wants a minimal header they just include the .hpp, but if they want
speed, to have things inlined they include the .hpp and the .ipp. Thus
the user has the option to choose.
> > > 3) I need serious help in creating some sort of build system. I
> > > realize this is a touchy subject since Boost doesn't yet have a
> > > standard way of handling this, but I'll settle for multiple
> platform
> > > specific makefiles much as Regex does. I'm just not qualified to
> > > handle this part.
> > >
> >
> > I can probably help you out on that. Let me see what I can come up
> with.
>
> I'd appreciate the help. We need to coordinate things like this so
> that multiple people aren't working on the same thing. Are you
> volunteering for specific platforms?
>
Yes I am. I can write autoconf/automake scripts. While I can only test
them on linux and cygwin, in theory, it should be portable to any Unix
that has pthreads installed.
--Dan Nuffer
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk