Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2005-04-24 08:07:11


What are the design goals of read_write_mutex? (Lock proliferation aside for
a moment.)

My understanding has always been that read/write locks are an optimization,
that is, a read/write lock-based algorithm should deliver better performance
than the same algorithm with "ordinary" locks. Right?

Wrong.

The program at the end of this message demonstrates that in this specific
(contrived?) case ordinary mutexes outperform a read/write mutex by a factor
of 2.5 or more in almost every scenario, even when no writers are active!

In some scenarios (16 readers, 4 writers, 10,000,000 iterations) the
ordinary mutex case completes in under 8 seconds on my machine, but the
read/write case exceeded my patience threshold.

Am I missing something?

--
Peter Dimov
http://www.pdimov.com
#include <boost/thread.hpp>
#include <boost/thread/read_write_mutex.hpp>
#include <iostream>
#include <vector>
#include <time.h>
//#define RWLOCK
int const n = 1000000;
int const n_readers = 16;
int const n_writers = 0;
std::vector<int> v;
#ifdef RWLOCK
boost::read_write_mutex mtx( 
boost::read_write_scheduling_policy::alternating_many_reads );
#else
boost::mutex mtx;
#endif
void reader_thread()
{
    int m = 0;
    for( int i = 0; i < n; ++i )
    {
#ifdef RWLOCK
        boost::read_write_mutex::scoped_read_lock lock( mtx );
#else
        boost::mutex::scoped_lock lock( mtx );
#endif
        m += v[ i ];
    }
    std::cout << m << std::endl;
}
void writer_thread()
{
    for( int i = 0; i < n; ++i )
    {
#ifdef RWLOCK
        boost::read_write_mutex::scoped_write_lock lock( mtx );
#else
        boost::mutex::scoped_lock lock( mtx );
#endif
        v[ i ] += i;
    }
}
int main()
{
    v.resize( n );
    boost::thread_group group;
    clock_t t = clock();
    for( int i = 0; i < n_writers; ++i )
    {
        group.add_thread( new boost::thread( writer_thread ) );
    }
    for( int i = 0; i < n_readers; ++i )
    {
        group.add_thread( new boost::thread( reader_thread ) );
    }
    group.join_all();
    t = clock() - t;
    std::cout << static_cast<double>( t ) / CLOCKS_PER_SEC << '\n';
}

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk