[thread] Does this condition wrapper perform better than the wrapped condition?

Hello, In the Join library I have see the following idiom mutex mtx; condition_variable cond; unsigned num_blocked; void foo() { unique_lock l(mtx); ++num_blocked; cond.wait(lock); --num_blocked; // ... } void foo() { unique_lock l(mtx); // ... if (num_blocked > 0) cond.notify_one(); // ... } Does this perform better in some contexts? if yes in which ones? If yes, does this justify a condition wrapper like: template < class Condition
class condition_booster{ public: typedef Condition condition; void notify_one() { if (num_blocked > 0) cond.notify_one(); } void notify_all() { if (num_blocked > 0) cond.notify_all(); } template <typename Locker, typename Predicate> template <typename Locker> void wait(Locker& lock) { ++num_blocked; cond.wait(lock); --num_blocked; } void wait(Locker& lock, Predicate& pred) { while(!pred()) wait(lock); } // ... private: Condition cond; unsigned num_blocked; }; Best _____________________ Vicente Juan Botet Escriba

"vicente.botet" <vicente.botet@wanadoo.fr> writes:
In the Join library I have see the following idiom
mutex mtx; condition_variable cond; unsigned num_blocked;
void foo() { unique_lock l(mtx); ++num_blocked; cond.wait(lock); --num_blocked;
// ... }
void foo() { unique_lock l(mtx); // ... if (num_blocked > 0) cond.notify_one(); // ... }
Does this perform better in some contexts? if yes in which ones?
It really shouldn't do. The check is part of the notify. Anthony -- Anthony Williams | Just Software Solutions Ltd Custom Software Development | http://www.justsoftwaresolutions.co.uk Registered in England, Company Number 5478976. Registered Office: 15 Carrallack Mews, St Just, Cornwall, TR19 7UL

----- Original Message ----- From: "Anthony Williams" <anthony_w.geo@yahoo.com> To: <boost@lists.boost.org> Sent: Monday, May 19, 2008 10:47 PM Subject: Re: [boost] [thread] Does this condition wrapper perform betterthan the wrapped condition?
"vicente.botet" <vicente.botet@wanadoo.fr> writes:
In the Join library I have see the following idiom
mutex mtx; condition_variable cond; unsigned num_blocked;
void foo() { unique_lock l(mtx); ++num_blocked; cond.wait(lock); --num_blocked;
// ... }
void foo() { unique_lock l(mtx); // ... if (num_blocked > 0) cond.notify_one(); // ... }
Does this perform better in some contexts? if yes in which ones?
It really shouldn't do. The check is part of the notify.
On windows notify_one is defined as: void notify_one() { if(detail::interlocked_read_acquire(&total_count)) { boost::mutex::scoped_lock internal_lock(internal_mutex); // ... } } detail::interlocked_read_acquire do a system call. This should be more expensive than doing a test >0, isn't it? With pthreads notify_one is defined as inline void condition_variable::notify_one() { BOOST_VERIFY(!pthread_cond_signal(&cond)); } Does pthread_cond_signal needs to protect its own counter from multiple threads? Could some one point to the pthread_cond_signal source code, or how to get it? Note that this idiom is only applicable if the application use the same lock to wait and to notify, which is quite current. Yigong, could you confirm some performance improvements on your approach? Vicente

"vicente.botet" <vicente.botet@wanadoo.fr> writes:
From: "Anthony Williams" <anthony_w.geo@yahoo.com>
"vicente.botet" <vicente.botet@wanadoo.fr> writes:
In the Join library I have see the following idiom
mutex mtx; condition_variable cond; unsigned num_blocked;
void foo() { unique_lock l(mtx); ++num_blocked; cond.wait(lock); --num_blocked;
// ... }
void foo() { unique_lock l(mtx); // ... if (num_blocked > 0) cond.notify_one(); // ... }
Does this perform better in some contexts? if yes in which ones?
It really shouldn't do. The check is part of the notify.
On windows notify_one is defined as:
void notify_one() { if(detail::interlocked_read_acquire(&total_count)) { boost::mutex::scoped_lock internal_lock(internal_mutex); // ... } }
detail::interlocked_read_acquire do a system call.
Not with MSVC it doesn't: it's just a plain volatile read and a compiler barrier to prevent optimizations changing the ordering. See boost/thread/win32/interlocked_read.hpp
This should be more expensive than doing a test >0, isn't it?
It could be on non-MSVC compilers.
With pthreads notify_one is defined as
inline void condition_variable::notify_one() { BOOST_VERIFY(!pthread_cond_signal(&cond)); }
Does pthread_cond_signal needs to protect its own counter from multiple threads? Could some one point to the pthread_cond_signal source code, or how to get it?
pthread_cond_signal is the POSIX condition variable notify. You can get the source code from your favourite linux distro. The POSIX standard requires that it is thread-safe and only notifies threads currently waiting on the cond var: if there aren't any it does nothing.
Note that this idiom is only applicable if the application use the same lock to wait and to notify, which is quite current.
In general, you don't need to hold a mutex across the notify. If you take an extra lock in order to check the count, you're imposing unnecessary synchronization. Anthony -- Anthony Williams | Just Software Solutions Ltd Custom Software Development | http://www.justsoftwaresolutions.co.uk Registered in England, Company Number 5478976. Registered Office: 15 Carrallack Mews, St Just, Cornwall, TR19 7UL

Hi, I would like to copy binary files from host A to host B. That for I was thinking to use boost MPI and open file on one side read buffer and send it to other side. bool SendFile(std::ifstream* inputFile) { bool ret = true; if (inputFile != NULL) { CData data; while (inputFile->eof() == false) { inputFile->read(data.GetDataBuffer(), data.GetDataBufferSize()); std::streamsize nRead = inputFile->gcount (); data.SetDataLen(nRead); GetWorld().send(1, MSG_CDATA, data); } inputFile->close(); } return ret; } To complicate a litle bit I may use filters (ZIP, Encrypt, ...) for this operation. Any idea/sample hoe to implement that? Is it possibale to do steaming using MPI? Thanks Ervin

Hi, On Tue, May 20, 2008 at 2:04 PM, Adrovic, Ervin <ervin.adrovic@hp.com> wrote:
Hi,
I would like to copy binary files from host A to host B. That for I was thinking to use boost MPI and open file on one side read buffer and send it to other side.
If You just want to copy files then using MPI is IMHO an overkill. Boost.Asio is probably a better choice.
bool SendFile(std::ifstream* inputFile) { bool ret = true; if (inputFile != NULL) { CData data; while (inputFile->eof() == false) { inputFile->read(data.GetDataBuffer(), data.GetDataBufferSize()); std::streamsize nRead = inputFile->gcount (); data.SetDataLen(nRead); GetWorld().send(1, MSG_CDATA, data); } inputFile->close(); }
return ret; }
To complicate a litle bit I may use filters (ZIP, Encrypt, ...) for this operation.
Any idea/sample hoe to implement that? Is it possibale to do steaming using MPI?
Thanks Ervin _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- ________________ ::matus_chochlik

Thanks Matus, Do you have any sample how to copy list of files using boost.asio? It is not just to stream binary data of file I need to send some meta data (filenames, ...) for multiple files. Is there any standard way doing that? Thanks Ervin -----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Matus Chochlik Sent: Tuesday, May 20, 2008 16:11 To: boost@lists.boost.org Subject: Re: [boost] MPI and file copy Hi, On Tue, May 20, 2008 at 2:04 PM, Adrovic, Ervin <ervin.adrovic@hp.com> wrote:
Hi,
I would like to copy binary files from host A to host B. That for I was thinking to use boost MPI and open file on one side read buffer and send it to other side.
If You just want to copy files then using MPI is IMHO an overkill. Boost.Asio is probably a better choice.
bool SendFile(std::ifstream* inputFile) { bool ret = true; if (inputFile != NULL) { CData data; while (inputFile->eof() == false) { inputFile->read(data.GetDataBuffer(), data.GetDataBufferSize()); std::streamsize nRead = inputFile->gcount (); data.SetDataLen(nRead); GetWorld().send(1, MSG_CDATA, data); } inputFile->close(); }
return ret; }
To complicate a litle bit I may use filters (ZIP, Encrypt, ...) for this operation.
Any idea/sample hoe to implement that? Is it possibale to do steaming using MPI?
Thanks Ervin _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- ________________ ::matus_chochlik _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Hi Ervin, On Wed, May 21, 2008 at 8:15 AM, Adrovic, Ervin <ervin.adrovic@hp.com> wrote:
Thanks Matus,
Do you have any sample how to copy list of files using boost.asio? It is not just to stream binary data of file I need to send some meta data (filenames, ...) for multiple files. Is there any standard way doing that?
I would suggest looking at FTP, SFTP or SCP specification and turning it to your needs. Here is the link to the FTP protocol specification: http://www.w3.org/Protocols/rfc959/ I don't have any sample code how to do it with Boost.Asio, but there are lots of working examples of FTP servers/clients on the Web and Asio has a good documentation including the whole sources of several similar apps. Hope it helps :) best regards, -- ________________ ::matus_chochlik

on Tue May 20 2008, "Adrovic, Ervin" <ervin.adrovic-AT-hp.com> wrote:
Hi,
I would like to copy binary files from host A to host B. That for I was thinking to use boost MPI and open file on one side read buffer and send it to other side.
bool SendFile(std::ifstream* inputFile) { bool ret = true; if (inputFile != NULL) { CData data; while (inputFile->eof() == false) { inputFile->read(data.GetDataBuffer(), data.GetDataBufferSize()); std::streamsize nRead = inputFile->gcount (); data.SetDataLen(nRead); GetWorld().send(1, MSG_CDATA, data); } inputFile->close(); }
return ret; }
To complicate a litle bit I may use filters (ZIP, Encrypt, ...) for this operation.
Any idea/sample hoe to implement that? Is it possibale to do steaming using MPI?
The only thing you need in order to ship bytes over Boost.MPI is a Boost.Serialization-compatible interface to those bytes. I would build a small serializable wrapper that, when serialized out to an Archive, reads the bytes to be archived from the underlying ifstream. Then you do the opposite procedure on the receiving end. HTH, -- Dave Abrahams BoostPro Computing http://www.boostpro.com

Thanks David, Since I am new with boost any sample hot to do that? Ervin -----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of David Abrahams Sent: Wednesday, May 21, 2008 08:33 To: boost@lists.boost.org Subject: Re: [boost] MPI and file copy on Tue May 20 2008, "Adrovic, Ervin" <ervin.adrovic-AT-hp.com> wrote:
Hi,
I would like to copy binary files from host A to host B. That for I was thinking to use boost MPI and open file on one side read buffer and send it to other side.
bool SendFile(std::ifstream* inputFile) { bool ret = true; if (inputFile != NULL) { CData data; while (inputFile->eof() == false) { inputFile->read(data.GetDataBuffer(), data.GetDataBufferSize()); std::streamsize nRead = inputFile->gcount (); data.SetDataLen(nRead); GetWorld().send(1, MSG_CDATA, data); } inputFile->close(); }
return ret; }
To complicate a litle bit I may use filters (ZIP, Encrypt, ...) for this operation.
Any idea/sample hoe to implement that? Is it possibale to do steaming using MPI?
The only thing you need in order to ship bytes over Boost.MPI is a Boost.Serialization-compatible interface to those bytes. I would build a small serializable wrapper that, when serialized out to an Archive, reads the bytes to be archived from the underlying ifstream. Then you do the opposite procedure on the receiving end. HTH, -- Dave Abrahams BoostPro Computing http://www.boostpro.com _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (5)
-
Adrovic, Ervin
-
Anthony Williams
-
David Abrahams
-
Matus Chochlik
-
vicente.botet