`
aigo
  • 浏览: 2537685 次
  • 性别: Icon_minigender_1
  • 来自: 宜昌
社区版块
存档分类
最新评论

Condition variables performance of boost, Win32, and the C++11 standard library

 
阅读更多

原文:http://codesequoia.wordpress.com/2013/03/27/condition-variables-performance-of-boost-win32-and-the-c11-standard-library/

 

About four years ago, I wrote the condition variables in Win32 API was much faster than boost threading library implementation. Since then the boost threading library has been rewritten and C++11 has introduced the threading support in the standard library. Let’s revisit the benchmark again.

The test program is bounded FIFO implemented with two condition variables. It passes 10,000,000 integers from the producer to the consumer. The test is conducted 50 times with the following environment.

– Intel(R) Core (TM) i7 950@3GHz.
– Windows 7 Professional
– Visual Studio 2012 Express (Update 1)

The average speed is shown here. Shorter is faster. Notice that it’s the result of 10 million times FIFO access. Although std::condition_variable is slower than others, the difference is pretty much nothing.



 

However, the distributions of elapsed time are still interesting. Among 50 times trial, Win32 and boost condition variables have pretty stable performance.



 

 

 

 

 

For unknown reason, however, std::condition_variable of Visual Studio 2012 Update 1 implementation sometimes takes very long time.



 

Here is the test program:

#include <boost/thread.hpp>
#include <boost/timer.hpp>
#include <deque>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <windows.h>
 
using namespace std;
 
class fifo
{
public:
    virtual ~fifo(){}
    virtual void push(int v) = 0;
    virtual int  pull()      = 0;
};
 
class boost_fifo : public fifo
{
public:
    boost_fifo(std::size_t s) : max_fifo_size(s){}
 
    void push(int v)
    {
        boost::mutex::scoped_lock lk(mtx);
        while(buffer.size() > max_fifo_size)
        {
            cv_slot.wait(lk);
        }
        buffer.push_back(v);
        cv_data.notify_one();
    }
 
    int pull()
    {
        boost::mutex::scoped_lock lk(mtx);
        while(buffer.empty())
        {
            cv_data.wait(lk);
        }
        int v = buffer.front();
        buffer.pop_front();
        cv_slot.notify_one();
        return v;
    }
private:
    std::size_t max_fifo_size;
    boost::mutex mtx;
    boost::condition_variable cv_slot;
    boost::condition_variable cv_data;
    std::deque<int> buffer;
};
 
class win32_fifo : public fifo
{
public:
    win32_fifo(std::size_t s) : max_fifo_size(s)
    {
        InitializeCriticalSection(&mtx);
        InitializeConditionVariable(&cv_slot);
        InitializeConditionVariable(&cv_data);
    }
 
    ~win32_fifo()
    {
        DeleteCriticalSection(&mtx);
    }
 
    void push(int v)
    {
        EnterCriticalSection(&mtx);
        while(buffer.size() > max_fifo_size)
        {
            SleepConditionVariableCS(&cv_slot, &mtx, INFINITE);
        }
        buffer.push_back(v);
        WakeConditionVariable(&cv_data);
        LeaveCriticalSection(&mtx);
    }
 
    int pull()
    {
        EnterCriticalSection(&mtx);
        while(buffer.empty())
        {
            SleepConditionVariableCS(&cv_data, &mtx, INFINITE);
        }
 
        int v = buffer.front();
        buffer.pop_front();
        WakeConditionVariable(&cv_slot);
        LeaveCriticalSection(&mtx);
        return v;
    }
private:
    std::size_t max_fifo_size;
    CRITICAL_SECTION mtx;
    CONDITION_VARIABLE cv_slot;
    CONDITION_VARIABLE cv_data;
    std::deque<int> buffer;
};
 
class std_fifo : public fifo
{
public:
    std_fifo(std::size_t s) : max_fifo_size(s){}
 
    void push(int v)
    {
        std::unique_lock<std::mutex> lk(mtx);
        while(buffer.size() > max_fifo_size)
        {
            cv_slot.wait(lk);
        }
        buffer.push_back(v);
        cv_data.notify_one();
    }
 
    int pull()
    {
        std::unique_lock<std::mutex> lk(mtx);
        while(buffer.empty())
        {
            cv_data.wait(lk);
        }
        int v = buffer.front();
        buffer.pop_front();
        cv_slot.notify_one();
        return v;
    }
private:
    std::size_t max_fifo_size;
    std::mutex mtx;
    std::condition_variable cv_slot;
    std::condition_variable cv_data;
    std::deque<int> buffer;
};
 
void push_loop(fifo* fifo_buffer)
{
    for(int i = 0; i < 10000000; i++)
    {
        fifo_buffer->push(i);
    }
}
 
void pull_loop(fifo* fifo_buffer)
{
    for(int i = 0; i < 10000000; i++)
    {
        fifo_buffer->pull();
    }
}
 
int main()
{
    vector<double> elapsedTime[3];
     
    static size_t const FIFO_SIZE = 16;
    for(int i = 0; i < 50; i++)
    {
        cerr << "BOOST FIFO: " << endl;
        {
            boost::timer tim;
            unique_ptr<fifo> fifo_buffer(new boost_fifo(FIFO_SIZE));
            boost::thread push_thread(bind(push_loop, fifo_buffer.get()));
            boost::thread pull_thread(bind(pull_loop, fifo_buffer.get()));
             
            push_thread.join();
            pull_thread.join();
 
            elapsedTime[0].push_back(tim.elapsed());
        }
 
        cerr << "WIN32 FIFO: " << endl;
        {
            boost::timer tim;
            unique_ptr<fifo> fifo_buffer(new win32_fifo(FIFO_SIZE));
            boost::thread push_thread(bind(push_loop, fifo_buffer.get()));
            boost::thread pull_thread(bind(pull_loop, fifo_buffer.get()));
             
            push_thread.join();
            pull_thread.join();
             
            elapsedTime[1].push_back(tim.elapsed());
        }
 
        cerr << "STD FIFO: " << endl;
        {
            boost::timer tim;
            unique_ptr<fifo> fifo_buffer(new std_fifo(FIFO_SIZE));
            boost::thread push_thread(bind(push_loop, fifo_buffer.get()));
            boost::thread pull_thread(bind(pull_loop, fifo_buffer.get()));
             
            push_thread.join();
            pull_thread.join();
             
            elapsedTime[2].push_back(tim.elapsed());
        }
    }
     
    for(auto v : elapsedTime)
    {
        for(auto e : v)
        {
            cout << e << ", ";
        }
        cout << endl;
    }
 
    return 1;
}

 

 

I used the following R code generate the graph. It also contains the raw data of elapsed time.

std <- c(5.183,  5.701,  7.006,  5.839,  5.524, 16.463,  8.336,  7.041,
         5.574,  5.098,  5.430,  5.034,  5.244,  6.088,  7.478,  5.557,
         5.062,  5.577,  5.266,  5.991,  5.900,  6.804,  6.452,  6.981,
         10.586, 7.152, 37.248,  5.469, 12.113,  6.645,  8.030, 10.559,
         10.695, 6.878,  6.321, 11.659,  6.210, 17.335,  5.804,  6.146,
         5.067,  5.709,  5.938,  5.718,  8.967,  7.143,  5.078,  7.472,
         5.347, 15.000)
 
boost <- c(6.104, 6.11, 5.862, 5.07, 5.311, 5.639, 5.402, 5.532, 5.61,
           5.686, 6.129, 5.481, 5.07, 5.602, 5.276, 6.046, 5.818, 6.209,
           6.111, 6.165, 5.828, 6.266, 5.806, 6.087, 5.708, 6.119, 6.406,
           6.096, 6.005, 6.332, 6.522, 6.91, 6.921, 5.765, 6.223, 5.444,
           6.274, 6.603, 5.717, 6.471, 5.968, 6.188, 6.608, 5.333, 5.506,
           5.507, 6.241, 5.981, 5.915, 6.515)
 
win32 <- c(4.356, 5.354, 4.641, 7.821, 4.664, 4.593, 7.174, 5.596, 4.493,
           4.353, 8.678, 4.459, 5.135, 4.526, 5.043, 4.997, 5.148, 5.03,
           7.421, 6.344, 7.64, 5.491, 6.101, 6.054, 6.626, 6.292, 6.29,
           6.912, 5.691, 5.991, 6.263, 6.096, 6.544, 8.024, 6.405, 6.216,
           6.157, 5.821, 7.759, 5.454, 6.364, 8.168, 8.471, 5.108, 6.192,
           5.385, 5.427, 5.855, 6.099, 5.539)
 
avg <- c(mean(std), mean(boost), mean(win32))
 
png("cv_comp_average.png")
barplot(avg, main="Condition Variable Comparison", names.arg = c("STD", "boost", "win32"), ylab="Elapsed Time (seconds)", ylim=c(0, 10))
dev.off()
 
png("cv_comp_std_dist.png")
hist(std, main="STD elapsed time histgram", xlab="Elapsed Time (seconds)", breaks=seq(0, 50, 1.0), ylim=c(0, 30))
dev.off()
 
png("cv_comp_boost_dist.png")
hist(boost, main="boost elapsed time histgram", xlab="Elapsed Time (seconds)", breaks=seq(0, 50, 1.0), ylim=c(0, 30))
dev.off()
 
png("cv_comp_win32_dist.png")
hist(boost, main="win32 elapsed time histgram", xlab="Elapsed Time (seconds)", breaks=seq(0, 50, 1.0), ylim=c(0, 30))
dev.off()

 

  • 大小: 3.6 KB
  • 大小: 3.6 KB
  • 大小: 3.7 KB
  • 大小: 4.2 KB
分享到:
评论

相关推荐

    C++ Standard Library Quick Reference

    the C++11 and C++14 standards have added even more efficient container classes, a new powerful regular expression library, and a portable multithreading library featuring threads, mutexes, condition ...

    C++ Standard Library Quick Reference(Apress,2016)

    the C++11 and C++14 standards have added even more efficient container classes, a new powerful regular expression library, and a portable multithreading library featuring threads, mutexes, condition ...

    Sams Teach Yourself C++ in One Hour a Day (8th Edition).pdf(21天学通C++ 第8版 英文版)

    arrays, variables, and smart pointers * Learn to expand your program's power with inheritance and polymorphism * Master the features of C++ by learning from programming experts * Works with all ANSI ...

    《C++ for Java Programmers》高清完整英文PDF版

    abnormal control flow, input and output, collections: the standard template library, primitive arrays and strings, C-style C++, and using Java and C++: the JNI. For new C++ programmers converted from ...

    C++标准(Standard for Programming Language C++)

    17.2 The C standard library 17.3 Definitions 17.4 Additional definitions 17.5 Method of description (Informative) 17.6 Library-wide requirements 18 Language support library 18.1 General 18.2 ...

    An Introduction to GCC

    profiling and coverage testing, paths and environment variables, and the C++ standard library and templates. Features a special foreword by Richard M. Stallman, principal developer of GCC and ...

    Google C++ International Standard.pdf

    4.4 The C++ memory model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 4.5 The C++ object model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ...

    Library to build PHP extensions with C++

    The PHP-CPP library is a C++ library for developing PHP extensions. It offers a collection of well documented and easy-to-use classes that can be used and extended to build native extensions for ...

    Java.Threads.and.the.Concurrency.Utilities.1484216997

    In Part 1, you learn about Thread API basics and runnables, synchronization and volatility, waiting and notification, and the additional capabilities of thread groups, thread local variables, and the ...

    PyQt5_sip-4.19.14-cp37-none-win_amd64.whl

    One of the features of Python ... SIP also makes it easy to take a Python application (maybe a prototype) and selectively implement parts of the application (maybe for performance reasons) in C or C++.

    Google C++ Style Guide(Google C++编程规范)高清PDF

    link ▶Use standard order for readability and to avoid hidden dependencies: C library, C++ library, other libraries' .h, your project's .h. All of a project's header files should be listed as ...

    paxCompiler for Delphi XE5 (Win32)

    paxCompiler is an embeddable compiler of the Object Pascal, Basic and JavaScript programming languages. The key features of the paxCompiler are: The compiler generates machine code for Intel ...

    Practical C++ Programming C++编程实践

    Standard Template Library STL Basics Class List-A Set of Students Creating a Waiting List with the STL List Storing Grades in a STL Map Putting It All Together Practical Considerations When Using the...

    超清晰PDF C++

    Origins of the C++ Language 2 C++ and Object-Oriented Programming 3 The Character of C++ 3 C++ Terminology 4 A Sample C++ Program 4 1.2 VARIABLES, EXPRESSIONS, AND ASSIGNMENT STATEMENTS 6 Identifiers ...

    《C++游戏编程入门》(Beginning C++ Game Programming)

    re ready to jump into the world of programming for games, "Beginning C++Game Programming" will get you started on your journey, providing you with a solid foundation in the game programming language ...

    Jumping Into C++ 完整英文版.pdf

    Jumping Into C++高清文字版本. Want to learn to code?...Data structures and the standard template library (STL) Key concepts are reinforced with quizzes and over 75 practice problems.

    C++ by Example

    Every day, more and more people learn and use the C++ programming Language. I have taught C to thousands of students in my life. I see many of those students now moving to C++ in their school work or ...

    Iterative Solution of Nonlinear Equations in Several Variables

    Iterative Solution of Nonlinear Equations in Several Variables provides a survey of the theoretical results on systems of nonlinear equations in finite dimension and the major iterative methods for ...

    Turbo C++ 3.0[DISK]

    For the latest information about Turbo C++ and its accompanying programs and manuals, read this file in its entirety. TABLE OF CONTENTS ----------------- 1. How to Get Help 2. Installation 3. ...

Global site tag (gtag.js) - Google Analytics