Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00014 #define BOOST_ENABLE_ASSERT_HANDLER 1
00015
00016 #include <boost/thread.hpp>
00017 #include <boost/bind.hpp>
00018 #include <boost/lexical_cast.hpp>
00019 #include "utils/measure-time.h"
00020 #include "utils/big-lock.h"
00021 #include "thread-pool.h"
00022 #include "task-manager.h"
00023 #include <systemc>
00024
00025 using namespace sc_core;
00026 using namespace std;
00027
00028 const int N = 100000;
00029
00030 void f(void) {
00031 ;
00032 }
00033
00034
00035 void eat_cpu(void) {
00036 for (int i = 0; i < 100000; ++i)
00037 for (int j = 0; j < 5540; ++j)
00038 continue;
00039 }
00040
00041 namespace boost
00042 {
00043 void assertion_failed(char const * expr, char const * function, char const * file, long line) {
00044 (void)expr; (void)function; (void)file; (void)line;
00045 perror("Assertion failed");
00046 }
00047 }
00048
00049 void send_requests(int n) {
00050 for (int i = 0; i < n; i++) {
00051 big_lock<0> l;
00052 sync_task t(f);
00053 l.unlock();
00054 thread_pool::get_instance()->queue(&t);
00055 t.wait_nosc();
00056 }
00057 }
00058
00059 void bench_pool_f(int nb_producers, boost::function<void()> fn) {
00060 boost::thread **ta = new boost::thread *[nb_producers];
00061
00062 measure_time t("pool (" + boost::lexical_cast<string>(nb_producers) + " producers)");
00063
00064 for (int i = 0; i < nb_producers; ++i)
00065 ta[i] = new boost::thread(fn);
00066 for (int i = 0; i < nb_producers; ++i)
00067 ta[i]->join();
00068 delete [] ta;
00069 }
00070
00071 void bench_pool(int nb_producers) {
00072 boost::function<void()> fn = boost::bind(send_requests, N/nb_producers);
00073 bench_pool_f(nb_producers, fn);
00074 }
00075
00076 void bench_thread(int nb_threads) {
00077 boost::thread **ta = new boost::thread *[nb_threads];
00078
00079 measure_time t("threads (" + boost::lexical_cast<string>(nb_threads) + " concurrent threads)");
00080
00081 for (int j = 0; j < N/nb_threads; ++j) {
00082 for (int i = 0; i < nb_threads; ++i)
00083 ta[i] = new boost::thread(f);
00084 for (int i = 0; i < nb_threads; ++i)
00085 ta[i]->join();
00086 }
00087 delete [] ta;
00088 }
00089
00090 void bench_pool_size(int size) {
00091 thread_pool::delete_instance();
00092 thread_pool::get_instance(size);
00093 cout << "10 tasks with a pool of "
00094 << thread_pool::get_instance()->get_nb_threads() << " threads" << endl;
00095 bench_pool(10);
00096 }
00097
00098 void bench_pool_eat(int nb_producers) {
00099 cout << nb_producers << " tasks with a pool of "
00100 << thread_pool::get_instance()->get_nb_threads() << " threads" << endl;
00101 measure_time t("pool eat");
00102 boost::function<void()> fn = boost::bind(eat_cpu);
00103 bench_pool_f(nb_producers, fn);
00104 }
00105
00106 int sc_main (int argc, char **argv) {
00107 (void)argc; (void)argv;
00108 thread_pool::get_instance();
00109 {
00110 measure_time t("eat cpu");
00111 eat_cpu();
00112 }
00113 {
00114 measure_time t("sequential call");
00115 for (int i = 0; i <= N; i++)
00116 f();
00117 }
00118 bench_pool(1);
00119 bench_pool(2);
00120 bench_pool(3);
00121 bench_pool(10);
00122 bench_pool(100);
00123
00124 bench_pool_size(1);
00125 bench_pool_size(2);
00126 bench_pool_size(3);
00127 bench_pool_size(10);
00128
00129 bench_pool_eat(1);
00130 bench_pool_eat(2);
00131 bench_pool_eat(3);
00132 bench_pool_eat(10);
00133
00134 bench_thread(1);
00135 bench_thread(2);
00136 bench_thread(3);
00137 bench_thread(10);
00138 {
00139 measure_time t("create+join");
00140 for (int i = 0; i <= N; i++) {
00141 boost::thread t(f);
00142 t.join();
00143 }
00144 }
00145 {
00146 boost::mutex m;
00147 measure_time t("mutex");
00148 for (int i = 0; i <= N; i++) {
00149 m.lock();
00150 m.unlock();
00151 }
00152
00153 }
00154 return 0;
00155 }