patterncppMinor
Testing a lock-free job queue
Viewed 0 times
freetestingqueuejoblock
Problem
I've created a lock-free job queue and with the tests I've written, which is also very fast.
That makes me doubt my benchmark procedure, so I'm hoping the collective knowledge will shed some light on the validity of those.
The test basically increments an atomic value (each job is a single increment) until the predefined value is met. In my mind, this test really shows the overhead that the queue imposes because the workload is so simple.
I've tried to create a queue to which I can post jobs and pick up jobs from all threads, a true multiple read/write queue. The tests I've written try to test all use cases, including multi-read/multi-write.
boostasio push/pop functions:
mutex_queue:
For details on the lock-free push/pop, I suggest you look at GitHub, since it is a bit extensive to post here.
For completeness, here's the test setup in full:
```
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
using namespace chrono;
using namespace boost::asio;
typedef functionfunction_type;
template
struct boostasio
{
boostasio( size_t r = 1024 ) {}
void push_back( T t )
{
service_.post( t );
}
bool pop( T &t )
{
t = [](){};
return service_.run_one();
}
io_service service_;
};
template
struct mutex_queue
{
mutex_queue( size_t r = 1024 ) :
lock_(),
index_( 0 ),
data_( r )
{
data_.clear();
}
void push_back( const T &t )
{
lock_guard guard( lock_ );
data_.push_back( t );
}
bool pop( T &t
That makes me doubt my benchmark procedure, so I'm hoping the collective knowledge will shed some light on the validity of those.
The test basically increments an atomic value (each job is a single increment) until the predefined value is met. In my mind, this test really shows the overhead that the queue imposes because the workload is so simple.
I've tried to create a queue to which I can post jobs and pick up jobs from all threads, a true multiple read/write queue. The tests I've written try to test all use cases, including multi-read/multi-write.
boostasio push/pop functions:
T = function
void push_back( T t )
{
service_.post( t );
}
bool pop( T &t )
{
t = [](){};
return service_.run_one();
}mutex_queue:
void push_back( const T &t )
{
lock_guard guard( lock_ );
data_.push_back( t );
}
bool pop( T &t )
{
lock_guard guard( lock_ );
if ( index_ == data_.size() ) { return false; }
t = data_[ index_++ ];
return true;
}For details on the lock-free push/pop, I suggest you look at GitHub, since it is a bit extensive to post here.
For completeness, here's the test setup in full:
```
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
using namespace chrono;
using namespace boost::asio;
typedef functionfunction_type;
template
struct boostasio
{
boostasio( size_t r = 1024 ) {}
void push_back( T t )
{
service_.post( t );
}
bool pop( T &t )
{
t = [](){};
return service_.run_one();
}
io_service service_;
};
template
struct mutex_queue
{
mutex_queue( size_t r = 1024 ) :
lock_(),
index_( 0 ),
data_( r )
{
data_.clear();
}
void push_back( const T &t )
{
lock_guard guard( lock_ );
data_.push_back( t );
}
bool pop( T &t
Solution
One thing you should do is not use so many (if any)
Also, you have many extra returns in your
Finally, your indentation is really good, which is mandatory for readability. However, you do not follow standard C++ style for your braces. C++ uses the K&R style, which sets the braces for functions on the next line, but braces inside functions, such as those used in
using namespace statements. This does make it a bit easier to write code, but it also can cause many problems with methods being confused with each other. For a detailed discussion of this, check out this question on SO.Also, you have many extra returns in your
#include statements which make it look like many groups instead of just one.Finally, your indentation is really good, which is mandatory for readability. However, you do not follow standard C++ style for your braces. C++ uses the K&R style, which sets the braces for functions on the next line, but braces inside functions, such as those used in
ifs, loops, and switch statements, start on the same line, like this:void my_function()
{
while (true) {
std::cout<<"Something here...\n";
}
if (true) {
std::cout<<"Something else here...\n";
}
}Code Snippets
void my_function()
{
while (true) {
std::cout<<"Something here...\n";
}
if (true) {
std::cout<<"Something else here...\n";
}
}Context
StackExchange Code Review Q#58321, answer score: 7
Revisions (0)
No revisions yet.