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()
相关推荐
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 ...
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 ...
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 ...
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 ...
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 ...
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 ...
4.4 The C++ memory model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 4.5 The C++ object model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ...
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 ...
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 ...
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++.
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 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 ...
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...
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 ...
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++高清文字版本. Want to learn to code?...Data structures and the standard template library (STL) Key concepts are reinforced with quizzes and over 75 practice problems.
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 provides a survey of the theoretical results on systems of nonlinear equations in finite dimension and the major iterative methods for ...
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. ...