bench-at.cc 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // -*- mode: c++; coding: utf-8 -*-
  2. // ra-ra/bench - Benchmark for at() operator.
  3. // (c) Daniel Llorens - 2023
  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 <string>
  11. #include <cstdlib>
  12. #include "ra/bench.hh"
  13. using std::cout, std::endl, std::flush, ra::TestRecorder;
  14. using real = double;
  15. using ra::dim_t;
  16. // FIXME Bigd/Bigd at loop is an outlier
  17. int main()
  18. {
  19. ra::TestRecorder tr(std::cout);
  20. auto test = [&tr](auto && C, auto && I, int reps)
  21. {
  22. int M = C.len(0);
  23. int N = C.len(1);
  24. int O = I.len(0);
  25. C = 4*ra::_0 + ra::_1;
  26. I(ra::all, 0) = map([&](auto && i) { return i%M; }, ra::_0 + (std::rand() & 1));
  27. I(ra::all, 1) = map([&](auto && i) { return i%N; }, ra::_0 + (std::rand() & 1));
  28. int ref0 = sum(at(C, iter<1>(I))), val0 = 0;
  29. Benchmark bm { reps, 3 };
  30. auto report = [&](std::string const & tag, auto && bv)
  31. {
  32. tr.info(std::setw(5), std::fixed, bm.avg(bv)/M/N/1e-9, " ns [", bm.stddev(bv)/M/N/1e-9, "] ", tag)
  33. .test_eq(val0, ref0);
  34. };
  35. report("direct subscript",
  36. bm.run([&] {
  37. int val = 0;
  38. for (int i=0; i<O; ++i) {
  39. val += C(dim_t(I(i, 0)), dim_t(I(i, 1))); // conversions needed when I has runtime rank
  40. }
  41. val0 = val;
  42. }));
  43. report("at member + loop",
  44. bm.run([&] {
  45. int val = 0;
  46. for (int i=0; i<O; ++i) {
  47. val += C.at(I(i));
  48. }
  49. val0 = val;
  50. }));
  51. report("at op + iter",
  52. bm.run([&] {
  53. val0 = sum(at(C, iter<1>(I)));
  54. }));
  55. };
  56. tr.section("Bigs/Bigs");
  57. {
  58. ra::Big<int, 2> C({1000, 4}, ra::none);
  59. ra::Big<int, 2> I({1000, 2}, ra::none);
  60. test(C, I, 100);
  61. }
  62. tr.section("Bigd/Bigd");
  63. {
  64. ra::Big<int> C({1000, 4}, ra::none);
  65. ra::Big<int> I({1000, 2}, ra::none);
  66. test(C, I, 100);
  67. }
  68. // regression in b40c2d412be04c4c2b4758a332424c05257f71ff due to CellSmall copy ctor.
  69. tr.section("Small/Small");
  70. {
  71. ra::Small<int, 10, 4> C;
  72. ra::Small<int, 10, 2> I;
  73. test(C, I, 10000);
  74. }
  75. tr.section("Bigd/Bigs");
  76. {
  77. ra::Big<int> C({1000, 4}, ra::none);
  78. ra::Big<int, 2> I({1000, 2}, ra::none);
  79. test(C, I, 100);
  80. }
  81. tr.section("Bigs/Bigd");
  82. {
  83. ra::Big<int, 2> C({1000, 4}, ra::none);
  84. ra::Big<int> I({1000, 2}, ra::none);
  85. test(C, I, 100);
  86. }
  87. tr.section("Bigs/Small");
  88. {
  89. ra::Big<int, 2> C({1000, 4}, ra::none);
  90. ra::Small<int, 10, 2> I;
  91. test(C, I, 1000);
  92. }
  93. tr.section("Bigd/Small");
  94. {
  95. ra::Big<int> C({1000, 4}, ra::none);
  96. ra::Small<int, 10, 2> I;
  97. test(C, I, 1000);
  98. }
  99. // FIXME not supported atm bc small.at output type depends on the length of the subscript.
  100. // tr.section("Small/Bigs");
  101. // {
  102. // ra::Small<int, 10, 4> C;
  103. // ra::Big<int, 2> I({1000, 2}, ra::none);
  104. // test(C, I, 1000);
  105. // }
  106. return tr.summary();
  107. }