root/examples/unique_ptr_parallel.cpp

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. BOOST_AUTO_TEST_SUITE
  2. BOOST_AUTO_TEST_SUITE_END

   1 /******************************************************************************
   2 ** $Header: svn+ssh://jmmcg@svn.code.sf.net/p/libjmmcg/code/trunk/libjmmcg/examples/unique_ptr_parallel.cpp 2362 2018-10-24 06:52:17Z jmmcg $
   3 **
   4 ** Copyright (c) 2011 by J.M.McGuiness, coder@hussar.me.uk
   5 **
   6 ** This library is free software; you can redistribute it and/or
   7 ** modify it under the terms of the GNU Lesser General Public
   8 ** License as published by the Free Software Foundation; either
   9 ** version 2.1 of the License, or (at your option) any later version.
  10 **
  11 ** This library is distributed in the hope that it will be useful,
  12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14 ** Lesser General Public License for more details.
  15 **
  16 ** You should have received a copy of the GNU Lesser General Public
  17 ** License along with this library; if not, write to the Free Software
  18 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19 */
  20 
  21 #include "stdafx.h"
  22 
  23 #include "core/stats_output.hpp"
  24 
  25 #define BOOST_TEST_MODULE libjmmcg_tests
  26 #include <boost/test/included/unit_test.hpp>
  27 
  28 #include <boost/test/test_case_template.hpp>
  29 #include <boost/mpl/list.hpp>
  30 
  31 #include "core/ave_deviation_meter.hpp"
  32 #include "core/unique_ptr.hpp"
  33 #include "core/thread_wrapper.hpp"
  34 
  35 #include <boost/move/unique_ptr.hpp>
  36 
  37 #include <chrono>
  38 
  39 using namespace jmmcg;
  40 using namespace ppd;
  41 
  42 template<class Mdl>
  43 struct obj {
  44         using lock_traits=api_lock_traits<platform_api, Mdl>;
  45         using element_type=int;
  46         using deleter_t=jmmcg::default_delete<obj>;
  47 
  48         element_type const init;
  49 
  50         obj(element_type i) noexcept(true) : init(i) {}
  51         ~obj() noexcept(true) {}
  52 
  53         void deleter() {
  54                 deleter_t().operator()(this);
  55         }
  56 };
  57 
  58 using ptr_types=boost::mpl::list<
  59         std::unique_ptr<obj<heavyweight_threading>>,
  60         boost::movelib::unique_ptr<obj<heavyweight_threading>>,
  61         unique_ptr<obj<sequential_mode>, api_lock_traits<platform_api, sequential_mode>>,
  62         unique_ptr<obj<heavyweight_threading>, api_lock_traits<platform_api, heavyweight_threading>>
  63 >;
  64 using timed_results_t=ave_deviation_meter<unsigned long long>;
  65 
  66 template<class Element>
  67 struct cctor_thread final : public jmmcg::ppd::wrapper<jmmcg::ppd::platform_api, heavyweight_threading> {
  68         typedef jmmcg::ppd::wrapper<jmmcg::ppd::platform_api, heavyweight_threading> base_t;
  69         typedef std::vector<Element> cont_t;
  70         struct make {
  71                 typename cont_t::value_type::element_type::element_type i;
  72 
  73                 make() noexcept(true) : i() {}
  74 
  75                 typename cont_t::value_type operator ()() {
  76                         return typename cont_t::value_type(new typename cont_t::value_type::element_type(++i));
  77                 }
  78         };
  79 
  80         cont_t &cont;
  81 
  82         explicit  __stdcall cctor_thread(cont_t &c) noexcept(true)
  83         : base_t(), cont(c) {
  84         }
  85         __stdcall ~cctor_thread() noexcept(true) {
  86                 this->delete_thread();
  87         }
  88 
  89         bool __fastcall worker_fn(typename base_t::thread_context_t &) {
  90                 while (!cont.empty()) {
  91                         const typename cont_t::value_type tmp(std::move(cont.back()));
  92                         cont.pop_back();
  93                 }
  94                 return true;
  95         }
  96 };
  97 
  98 template<class Element>
  99 struct dtor_thread final : public jmmcg::ppd::wrapper<jmmcg::ppd::platform_api, heavyweight_threading> {
 100         typedef jmmcg::ppd::wrapper<jmmcg::ppd::platform_api, heavyweight_threading> base_t;
 101         typedef std::vector<Element> cont_t;
 102         struct make {
 103                 typename cont_t::value_type::element_type::element_type i;
 104 
 105                 make() noexcept(true) : i() {}
 106 
 107                 typename cont_t::value_type operator ()() {
 108                         return typename cont_t::value_type(new typename cont_t::value_type::element_type(++i));
 109                 }
 110         };
 111 
 112         cont_t &cont;
 113 
 114         explicit  __stdcall dtor_thread(cont_t &c) noexcept(true)
 115         : base_t(), cont(c) {
 116         }
 117         __stdcall ~dtor_thread() noexcept(true) {
 118                 this->delete_thread();
 119         }
 120 
 121         bool __fastcall worker_fn(typename base_t::thread_context_t &) {
 122                 while (!cont.empty()) {
 123                         cont.back().reset();
 124                         cont.pop_back();
 125                 }
 126                 return true;
 127         }
 128 };
 129 
 130 BOOST_AUTO_TEST_SUITE(performance_cctor, *boost::unit_test::fixture<jmmcg::stats_to_csv::wrapper>(std::string("unique_ptr_parallel_cctor.csv")))
 131 
 132 BOOST_AUTO_TEST_SUITE(unique_ptr_parallel_tests)
 133 
 134 /**
 135         \test <a href="./examples/unique_ptr_parallel_cctor.svg">Graph</a> of performance results for parallel unique_ptr cctors.
 136                         ==========================================================================================
 137         Results for 100000000 items:
 138 */
 139 BOOST_AUTO_TEST_CASE_TEMPLATE(parallel_cctor, ptr_t, ptr_types) {
 140         typedef cctor_thread<ptr_t> thread_t;
 141 #ifdef JMMCG_PERFORMANCE_TESTS
 142         const std::size_t num_items=100000000;
 143 #else
 144         const std::size_t num_items=100;
 145 #endif
 146         const unsigned short loops_for_conv=50;
 147         const double perc_conv_estimate=5.0;
 148 
 149         const std::pair<timed_results_t, bool> timed_results(compute_average_deviation<timed_results_t::value_type>(
 150                 perc_conv_estimate,
 151                 loops_for_conv,
 152                 []() {
 153                         typename thread_t::cont_t c;
 154                         std::generate_n(std::back_inserter(c), num_items, typename thread_t::make());
 155                         thread_t th1(c);
 156                         thread_t th2(c);
 157                         c.clear();
 158                         const auto t1=std::chrono::high_resolution_clock::now();
 159                         th1.create_running();
 160                         th2.create_running();
 161                         do {
 162                                 api_threading_traits<platform_api, heavyweight_threading>::sleep(100);
 163                         } while (th1.is_running() || th2.is_running());
 164                         const auto t2=std::chrono::high_resolution_clock::now();
 165                         BOOST_CHECK(th1.cont.empty());
 166                         BOOST_CHECK(th2.cont.empty());
 167                         BOOST_CHECK(c.empty());
 168                         return timed_results_t::value_type(num_items/(static_cast<double>(std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count())/1000000));
 169                 }
 170         ));
 171         std::cout<<typeid(ptr_t).name()<<" rate cctors/sec="<<timed_results.first<<std::endl;
 172 #ifdef JMMCG_PERFORMANCE_TESTS
 173         stats_to_csv::handle->stats<<timed_results.first.to_csv()<<std::flush;
 174         BOOST_CHECK(!timed_results.second);
 175 #endif
 176 }
 177 
 178 BOOST_AUTO_TEST_SUITE_END()
 179 
 180 BOOST_AUTO_TEST_SUITE(performance_cctor, *boost::unit_test::fixture<jmmcg::stats_to_csv::wrapper>(std::string("unique_ptr_parallel_dtor.csv")))
 181 
 182 /**
 183         \test <a href="./examples/unique_ptr_parallel_dtor.svg">Graph</a> of performance results for parallel unique_ptr dtors.
 184                         ==========================================================================================
 185         Results for 100000000 items:
 186 */
 187 BOOST_AUTO_TEST_CASE_TEMPLATE(parallel_deletes, ptr_t, ptr_types) {
 188         typedef dtor_thread<ptr_t> thread_t;
 189 #ifdef JMMCG_PERFORMANCE_TESTS
 190         const std::size_t num_items=100000000;
 191 #else
 192         const std::size_t num_items=100;
 193 #endif
 194         const unsigned short loops_for_conv=50;
 195         const double perc_conv_estimate=5.0;
 196 
 197         const std::pair<timed_results_t, bool> timed_results(compute_average_deviation<timed_results_t::value_type>(
 198                 perc_conv_estimate,
 199                 loops_for_conv,
 200                 []() {
 201                         typename thread_t::cont_t c;
 202                         std::generate_n(std::back_inserter(c), num_items, typename thread_t::make());
 203                         thread_t th1(c);
 204                         thread_t th2(c);
 205                         c.clear();
 206                         const auto t1=std::chrono::high_resolution_clock::now();
 207                         th1.create_running();
 208                         th2.create_running();
 209                         do {
 210                                 api_threading_traits<platform_api, heavyweight_threading>::sleep(100);
 211                         } while (th1.is_running() || th2.is_running());
 212                         const auto t2=std::chrono::high_resolution_clock::now();
 213                         BOOST_CHECK(th1.cont.empty());
 214                         BOOST_CHECK(th2.cont.empty());
 215                         BOOST_CHECK(c.empty());
 216                         return timed_results_t::value_type(num_items/(static_cast<double>(std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count())/1000000));
 217                 }
 218         ));
 219         std::cout<<typeid(ptr_t).name()<<" rate dtors/sec="<<timed_results.first<<std::endl;
 220 #ifdef JMMCG_PERFORMANCE_TESTS
 221         stats_to_csv::handle->stats<<timed_results.first.to_csv()<<std::flush;
 222         BOOST_CHECK(!timed_results.second);
 223 #endif
 224 }
 225 
 226 BOOST_AUTO_TEST_SUITE_END()
 227 
 228 BOOST_AUTO_TEST_SUITE_END()

/* [<][>][^][v][top][bottom][index][help] */