bench-sum-rows.cc 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // -*- mode: c++; coding: utf-8 -*-
  2. // ra-ra/bench - Various ways to sum rows.
  3. // (c) Daniel Llorens - 2016-2017
  4. // This library is free software; you can redistribute it and/or modify it under
  5. // the terms of the GNU Lesser General Public License as published by the Free
  6. // Software Foundation; either version 3 of the License, or (at your option) any
  7. // later version.
  8. #include <iostream>
  9. #include <iomanip>
  10. #include "ra/test.hh"
  11. #include "ra/bench.hh"
  12. using std::cout, std::endl, std::flush, ra::TestRecorder;
  13. using real = double;
  14. int main()
  15. {
  16. TestRecorder tr(cout);
  17. cout.precision(4);
  18. auto bench =
  19. [&tr](char const * tag, int m, int n, int reps, auto && f)
  20. {
  21. ra::Big<real, 2> a({m, n}, ra::_0 - ra::_1);
  22. ra::Big<real, 1> ref({n}, 0);
  23. iter<1>(ref) += iter<1>(a)*reps;
  24. ra::Big<real, 1> c({n}, ra::none);
  25. auto bv = Benchmark().repeats(reps).runs(3)
  26. .once_f([&](auto && repeat) { c=0.; repeat([&]() { f(c, a); }); });
  27. tr.info(std::setw(5), std::fixed, Benchmark::avg(bv)/(m*n)/1e-9, " ns [",
  28. Benchmark::stddev(bv)/(m*n)/1e-9 ,"] ", tag).test_eq(ref, c);
  29. };
  30. auto bench_all =
  31. [&](int m, int n, int reps)
  32. {
  33. tr.section(m, " x ", n, " times ", reps);
  34. bench("raw", m, n, reps,
  35. [](auto & c, auto const & a)
  36. {
  37. real const * __restrict__ ap = a.data();
  38. real * __restrict__ cp = c.data();
  39. ra::dim_t const m = a.len(0);
  40. ra::dim_t const n = a.len(1);
  41. for (ra::dim_t i=0; i!=m; ++i) {
  42. for (ra::dim_t j=0; j!=n; ++j) {
  43. cp[j] += ap[i*n+j];
  44. }
  45. }
  46. });
  47. bench("sideways", m, n, reps,
  48. [](auto & c, auto const & a)
  49. {
  50. for (int j=0, jend=a.len(1); j<jend; ++j) {
  51. c(j) += sum(a(ra::all, j));
  52. }
  53. });
  54. bench("accumrows", m, n, reps,
  55. [](auto & c, auto const & a)
  56. {
  57. for_each([&c](auto && a) { c += a; }, iter<1>(a));
  58. });
  59. bench("wrank1", m, n, reps,
  60. [](auto & c, auto const & a)
  61. {
  62. for_each(ra::wrank<1, 1>([](auto & c, auto && a) { c += a; }), c, a);
  63. });
  64. bench("wrank2", m, n, reps,
  65. [](auto & c, auto const & a)
  66. {
  67. for_each(ra::wrank<1, 1>(ra::wrank<0, 0>([](auto & c, auto a) { c += a; })), c, a);
  68. });
  69. bench("accumscalar", m, n, reps,
  70. [](auto & c, auto const & a)
  71. {
  72. ra::scalar(c) += iter<1>(a);
  73. });
  74. bench("accumiter", m, n, reps,
  75. [](auto & c, auto const & a)
  76. {
  77. iter<1>(c) += iter<1>(a);
  78. });
  79. bench("frametransp", m, n, reps,
  80. [](auto & c, auto const & a)
  81. {
  82. c += transpose<1, 0>(a);
  83. });
  84. };
  85. bench_all(1, 1000000, 20);
  86. bench_all(10, 100000, 20);
  87. bench_all(100, 10000, 20);
  88. bench_all(1000, 1000, 20);
  89. bench_all(10000, 100, 20);
  90. bench_all(100000, 10, 20);
  91. bench_all(1000000, 1, 20);
  92. bench_all(1, 10000, 2000);
  93. bench_all(10, 1000, 2000);
  94. bench_all(100, 100, 2000);
  95. bench_all(1000, 10, 2000);
  96. bench_all(10000, 1, 2000);
  97. return tr.summary();
  98. }