LCOV - code coverage report
Current view: top level - src/bindings/cpp/benchmarks - benchmark_sync.cpp (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 0 192 0.0 %
Date: 2019-09-12 12:28:41 Functions: 0 30 0.0 %

          Line data    Source code
       1             : /**
       2             :  * @file
       3             :  *
       4             :  * @brief
       5             :  *
       6             :  * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
       7             :  */
       8             : 
       9             : #include <kdbthread.hpp>
      10             : #include <kdbtimer.hpp>
      11             : 
      12             : // long long iterations = 100000000000LL; // elitebenchmark lookup
      13             : // long long iterations = 100000LL; // elitebenchmark with/activate
      14             : long long iterations = 1000LL; // elitebenchmark sync/reload benchmark
      15             : // long long iterations = 100LL; // valgrind
      16             : 
      17             : const int benchmarkIterations = 11; // is a good number to not need mean values for median
      18             : 
      19           0 : const std::string filename = "check.txt";
      20           0 : std::ofstream dump (filename);
      21             : 
      22             : const uint32_t value = 55;
      23             : const char * s_value = "55";
      24             : const uint32_t othervalue = 66;
      25             : const char * s_othervalue = "66";
      26             : 
      27           0 : kdb::ThreadInteger::type add_contextual (kdb::ThreadInteger const & i1, kdb::ThreadInteger const & i2)
      28             : {
      29           0 :         return i1 + i2;
      30             : }
      31             : 
      32           0 : std::unique_ptr<Timer> tSync[10]{
      33           0 :         std::unique_ptr<Timer> (new Timer ("layer sync0", Timer::quiet)), std::unique_ptr<Timer> (new Timer ("layer sync1", Timer::quiet)),
      34           0 :         std::unique_ptr<Timer> (new Timer ("layer sync2", Timer::quiet)), std::unique_ptr<Timer> (new Timer ("layer sync3", Timer::quiet)),
      35           0 :         std::unique_ptr<Timer> (new Timer ("layer sync4", Timer::quiet)), std::unique_ptr<Timer> (new Timer ("layer sync5", Timer::quiet)),
      36           0 :         std::unique_ptr<Timer> (new Timer ("layer sync6", Timer::quiet)), std::unique_ptr<Timer> (new Timer ("layer sync7", Timer::quiet)),
      37           0 :         std::unique_ptr<Timer> (new Timer ("layer sync8", Timer::quiet)), std::unique_ptr<Timer> (new Timer ("layer sync9", Timer::quiet))
      38           0 : };
      39             : 
      40           0 : std::vector<std::shared_ptr<kdb::ThreadInteger>> createCV (kdb::KeySet & ks, kdb::ThreadContext & tc, int N)
      41             : {
      42           0 :         std::vector<std::shared_ptr<kdb::ThreadInteger>> vi;
      43           0 :         for (long long i = 0; i < N; ++i)
      44             :         {
      45           0 :                 std::ostringstream os;
      46           0 :                 os << "/test/layer1";
      47             :                 /*
      48             :                 for (long long j = 0; j < i; ++j)
      49             :                 {
      50             :                         os << "/%layer" << j << "%";
      51             :                 }
      52             :                 */
      53           0 :                 os << "/" << i;
      54             :                 // std::cout << os.str().c_str() << std::endl;
      55           0 :                 vi.push_back (std::make_shared<kdb::ThreadInteger> (
      56           0 :                         ks, tc, kdb::Key (os.str ().c_str (), KEY_CASCADING_NAME, KEY_META, "default", s_value, KEY_END)));
      57             :         }
      58           0 :         return vi;
      59             : }
      60             : 
      61             : 
      62           0 : __attribute__ ((noinline)) void benchmark_layer_syncN (long long N)
      63             : {
      64           0 :         kdb::Coordinator c;
      65           0 :         kdb::ThreadContext tc (c);
      66           0 :         kdb::KeySet ks;
      67           0 :         kdb::ThreadInteger ti (ks, tc, kdb::Key ("/test/nolayer", KEY_CASCADING_NAME, KEY_META, "default", s_value, KEY_END));
      68           0 :         ti = 5;
      69           0 :         kdb::ThreadInteger::type x = ti;
      70             : 
      71           0 :         Timer & t = *tSync[N];
      72           0 :         t.start ();
      73           0 :         for (long long i = 0; i < iterations; ++i)
      74             :         {
      75           0 :                 tc.sync ();
      76           0 :                 x ^= add_contextual (ti, ti);
      77             :         }
      78           0 :         t.stop ();
      79           0 :         std::cout << t;
      80           0 :         dump << t.name << x << std::endl;
      81           0 : }
      82             : 
      83           0 : std::unique_ptr<Timer> tReload[10]{ std::unique_ptr<Timer> (new Timer ("layer reload0", Timer::quiet)),
      84           0 :                                     std::unique_ptr<Timer> (new Timer ("layer reload1", Timer::quiet)),
      85           0 :                                     std::unique_ptr<Timer> (new Timer ("layer reload2", Timer::quiet)),
      86           0 :                                     std::unique_ptr<Timer> (new Timer ("layer reload3", Timer::quiet)),
      87           0 :                                     std::unique_ptr<Timer> (new Timer ("layer reload4", Timer::quiet)),
      88           0 :                                     std::unique_ptr<Timer> (new Timer ("layer reload5", Timer::quiet)),
      89           0 :                                     std::unique_ptr<Timer> (new Timer ("layer reload6", Timer::quiet)),
      90           0 :                                     std::unique_ptr<Timer> (new Timer ("layer reload7", Timer::quiet)),
      91           0 :                                     std::unique_ptr<Timer> (new Timer ("layer reload8", Timer::quiet)),
      92           0 :                                     std::unique_ptr<Timer> (new Timer ("layer reload9", Timer::quiet)) };
      93             : 
      94           0 : __attribute__ ((noinline)) void benchmark_kdb_reloadN (long long N)
      95             : {
      96           0 :         kdb::Coordinator c;
      97           0 :         kdb::ThreadContext tc (c);
      98           0 :         kdb::KeySet ks;
      99           0 :         kdb::KDB kdb;
     100           0 :         kdb::KDB kdb2;
     101             : 
     102           0 :         kdb.get (ks, "/test");
     103           0 :         kdb2.get (ks, "/test");
     104           0 :         ks.append (kdb::Key ("system/test/key", KEY_VALUE, "value", KEY_END));
     105           0 :         kdb.set (ks, "/test");
     106           0 :         ks.append (kdb::Key ("system/test/key2", KEY_VALUE, "value2", KEY_END));
     107             :         // kdb2.set (ks, "/test");
     108             : 
     109           0 :         kdb::ThreadInteger ti (ks, tc, kdb::Key ("/test/nolayer", KEY_CASCADING_NAME, KEY_META, "default", s_value, KEY_END));
     110           0 :         ti = 5;
     111           0 :         kdb::ThreadInteger::type x = ti;
     112             : 
     113           0 :         Timer & t = *tReload[N];
     114             : 
     115           0 :         std::vector<kdb::KDB> kdbx;
     116           0 :         kdbx.resize (iterations); // really expensive operation, but need to be clean for every benchmark
     117             : 
     118           0 :         t.start ();
     119           0 :         for (long long i = 0; i < iterations; ++i)
     120             :         {
     121             :                 // kdb.set(ks, "/test");
     122           0 :                 kdbx[i].get (ks, "/test");
     123           0 :                 tc.sync ();
     124           0 :                 x ^= add_contextual (ti, ti);
     125             :         }
     126           0 :         t.stop ();
     127           0 :         std::cout << t;
     128           0 :         dump << t.name << x << std::endl;
     129           0 : }
     130             : 
     131             : 
     132             : template <int N>
     133           0 : class Layer : public kdb::Layer
     134             : {
     135             : public:
     136           0 :         std::string id () const override
     137             :         {
     138           0 :                 std::string ret ("layerX");
     139           0 :                 ret[5] = ('0' + N);
     140           0 :                 return ret;
     141             :         }
     142           0 :         std::string operator() () const override
     143             :         {
     144           0 :                 std::string ret ("X");
     145           0 :                 ret[0] = '0' + N;
     146           0 :                 return ret;
     147             :         }
     148             : };
     149             : 
     150             : 
     151           0 : std::unique_ptr<Timer> tSwitch[10]{ std::unique_ptr<Timer> (new Timer ("layer switch0", Timer::quiet)),
     152           0 :                                     std::unique_ptr<Timer> (new Timer ("layer switch1", Timer::quiet)),
     153           0 :                                     std::unique_ptr<Timer> (new Timer ("layer switch2", Timer::quiet)),
     154           0 :                                     std::unique_ptr<Timer> (new Timer ("layer switch3", Timer::quiet)),
     155           0 :                                     std::unique_ptr<Timer> (new Timer ("layer switch4", Timer::quiet)),
     156           0 :                                     std::unique_ptr<Timer> (new Timer ("layer switch5", Timer::quiet)),
     157           0 :                                     std::unique_ptr<Timer> (new Timer ("layer switch6", Timer::quiet)),
     158           0 :                                     std::unique_ptr<Timer> (new Timer ("layer switch7", Timer::quiet)),
     159           0 :                                     std::unique_ptr<Timer> (new Timer ("layer switch8", Timer::quiet)),
     160           0 :                                     std::unique_ptr<Timer> (new Timer ("layer switch9", Timer::quiet)) };
     161             : 
     162           0 : __attribute__ ((noinline)) void benchmark_layer_switchN (long long N)
     163             : {
     164           0 :         kdb::Coordinator c;
     165           0 :         kdb::ThreadContext tc (c);
     166           0 :         kdb::KeySet ks;
     167           0 :         kdb::ThreadInteger ti (ks, tc, kdb::Key ("/test/nolayer", KEY_CASCADING_NAME, KEY_META, "default", s_value, KEY_END));
     168           0 :         ti = 5;
     169           0 :         kdb::ThreadInteger::type x = ti;
     170             : 
     171           0 :         Timer & t = *tSwitch[N];
     172           0 :         t.start ();
     173           0 :         for (long long i = 0; i < iterations; ++i)
     174             :         {
     175           0 :                 if (N > 0) tc.activate<Layer<0>> ();
     176           0 :                 if (N > 1) tc.activate<Layer<1>> ();
     177           0 :                 if (N > 2) tc.activate<Layer<2>> ();
     178           0 :                 if (N > 3) tc.activate<Layer<3>> ();
     179           0 :                 if (N > 4) tc.activate<Layer<4>> ();
     180           0 :                 if (N > 5) tc.activate<Layer<5>> ();
     181           0 :                 if (N > 6) tc.activate<Layer<6>> ();
     182           0 :                 if (N > 7) tc.activate<Layer<7>> ();
     183           0 :                 if (N > 8) tc.activate<Layer<8>> ();
     184           0 :                 if (N > 9) tc.activate<Layer<9>> ();
     185           0 :                 x ^= add_contextual (ti, ti);
     186             :         }
     187           0 :         t.stop ();
     188           0 :         std::cout << t;
     189           0 :         dump << t.name << x << std::endl;
     190           0 : }
     191             : 
     192           0 : std::unique_ptr<Timer> tCV[10]{
     193           0 :         std::unique_ptr<Timer> (new Timer ("CV switch0", Timer::quiet)), std::unique_ptr<Timer> (new Timer ("CV switch1", Timer::quiet)),
     194           0 :         std::unique_ptr<Timer> (new Timer ("CV switch2", Timer::quiet)), std::unique_ptr<Timer> (new Timer ("CV switch3", Timer::quiet)),
     195           0 :         std::unique_ptr<Timer> (new Timer ("CV switch4", Timer::quiet)), std::unique_ptr<Timer> (new Timer ("CV switch5", Timer::quiet)),
     196           0 :         std::unique_ptr<Timer> (new Timer ("CV switch6", Timer::quiet)), std::unique_ptr<Timer> (new Timer ("CV switch7", Timer::quiet)),
     197           0 :         std::unique_ptr<Timer> (new Timer ("CV switch8", Timer::quiet)), std::unique_ptr<Timer> (new Timer ("CV switch9", Timer::quiet))
     198           0 : };
     199             : 
     200           0 : __attribute__ ((noinline)) void benchmark_cv_switchN (long long N)
     201             : {
     202           0 :         kdb::Coordinator c;
     203           0 :         kdb::ThreadContext tc (c);
     204           0 :         kdb::KeySet ks;
     205           0 :         kdb::ThreadInteger ti (ks, tc, kdb::Key ("/test/nolayer", KEY_CASCADING_NAME, KEY_META, "default", s_value, KEY_END));
     206           0 :         ti = 5;
     207           0 :         kdb::ThreadInteger::type x = ti;
     208             : 
     209           0 :         std::vector<std::shared_ptr<kdb::ThreadInteger>> vi = createCV (ks, tc, N);
     210             : 
     211           0 :         Timer & t = *tCV[N];
     212           0 :         t.start ();
     213           0 :         for (long long i = 0; i < iterations; ++i)
     214             :         {
     215           0 :                 if (N > 0) tc.activate (*vi[0]);
     216           0 :                 if (N > 1) tc.activate (*vi[1]);
     217           0 :                 if (N > 2) tc.activate (*vi[2]);
     218           0 :                 if (N > 3) tc.activate (*vi[3]);
     219           0 :                 if (N > 4) tc.activate (*vi[4]);
     220           0 :                 if (N > 5) tc.activate (*vi[5]);
     221           0 :                 if (N > 6) tc.activate (*vi[6]);
     222           0 :                 if (N > 7) tc.activate (*vi[7]);
     223           0 :                 if (N > 8) tc.activate (*vi[8]);
     224           0 :                 if (N > 9) tc.activate (*vi[9]);
     225           0 :                 x ^= add_contextual (ti, ti);
     226             :         }
     227           0 :         t.stop ();
     228           0 :         std::cout << t;
     229           0 :         dump << t.name << x << std::endl;
     230           0 : }
     231             : 
     232             : #include <unistd.h>
     233             : #ifdef _WIN32
     234             : #include <winsock2.h>
     235             : #endif
     236             : 
     237           0 : void computer_info ()
     238             : {
     239             :         char hostname[1024];
     240           0 :         gethostname (hostname, 1023);
     241           0 :         std::cout << std::endl;
     242           0 :         std::cout << std::endl;
     243           0 :         std::cout << "hostname " << hostname << std::endl;
     244             : #ifdef __GNUC__
     245           0 :         std::cout << "gcc: " << __GNUC__ << std::endl;
     246             : #endif
     247             : #ifdef __INTEL_COMPILER
     248             :         std::cout << "icc: " << __INTEL_COMPILER << std::endl;
     249             : #endif
     250             : #ifdef __clang__
     251             :         std::cout << "clang: " << __clang__ << std::endl;
     252             : #endif
     253           0 :         std::cout << "sizeof(int) " << sizeof (int) << std::endl;
     254           0 :         std::cout << "sizeof(long) " << sizeof (long) << std::endl;
     255           0 :         std::cout << "sizeof(long long) " << sizeof (long long) << std::endl;
     256           0 :         std::cout << "sizeof(Integer::type) " << sizeof (kdb::ThreadInteger::type) << std::endl;
     257           0 :         std::cout << "value " << value << std::endl;
     258           0 :         std::cout << "othervalue " << othervalue << std::endl;
     259           0 :         std::cout << "iterations " << iterations << std::endl;
     260           0 :         std::cout << "filename " << filename << std::endl;
     261           0 :         std::cout << std::endl;
     262           0 : }
     263             : 
     264           0 : int main (int argc, char ** argv)
     265             : {
     266           0 :         computer_info ();
     267           0 :         std::cout << std::endl;
     268             : 
     269             :         {
     270             :                 using namespace kdb;
     271           0 :                 std::string testRoot = "/test/";
     272           0 :                 Key parent (testRoot, KEY_END);
     273             : 
     274           0 :                 KDB first;
     275           0 :                 KeySet firstReturned;
     276           0 :                 first.get (firstReturned, parent);
     277           0 :                 firstReturned.append (Key ("system" + testRoot + "key1", KEY_VALUE, "value1", KEY_END));
     278             : 
     279           0 :                 KDB second;
     280           0 :                 KeySet secondReturned;
     281           0 :                 second.get (secondReturned, parent);
     282           0 :                 secondReturned.append (Key ("system" + testRoot + "key2", KEY_VALUE, "value2", KEY_END));
     283             : 
     284           0 :                 second.set (secondReturned, parent);
     285             :                 // first.set(firstReturned, parent); // exception expected
     286             :         }
     287             : 
     288           0 :         if (argc == 2)
     289             :         {
     290           0 :                 iterations = atoll (argv[1]);
     291             :         }
     292             : 
     293           0 :         for (int i = 0; i < benchmarkIterations; ++i)
     294             :         {
     295           0 :                 std::cout << i << std::endl;
     296           0 :                 for (int j = 0; j < 10; ++j)
     297             :                 {
     298           0 :                         benchmark_layer_syncN (j);
     299           0 :                         benchmark_kdb_reloadN (j);
     300           0 :                         benchmark_layer_switchN (j);
     301           0 :                         benchmark_cv_switchN (j);
     302             :                 }
     303             :         }
     304             : 
     305           0 :         for (int i = 0; i < 10; ++i)
     306             :         {
     307           0 :                 std::cerr << i << "," << tSync[i]->getMedian () << "," << tReload[i]->getMedian () << "," << tSwitch[i]->getMedian () << ","
     308           0 :                           << tCV[i]->getMedian () << std::endl;
     309             :         }
     310             : 
     311             :         // data << "value,benchmark" << std::endl;
     312           0 : }

Generated by: LCOV version 1.13