bench-optimize.cc 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // -*- mode: c++; coding: utf-8 -*-
  2. // ra-ra/bench - ET optimization.
  3. // (c) Daniel Llorens - 2017-2022
  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. #define RA_OPT // disable so we can compare with (forced) and without
  9. #ifdef RA_DO_OPT_SMALLVECTOR // bench requires 1 to be meaningful.
  10. #undef RA_DO_OPT_SMALLVECTOR
  11. #endif
  12. #define RA_DO_OPT_SMALLVECTOR 1
  13. #include <iostream>
  14. #include <iomanip>
  15. #include "ra/test.hh"
  16. using std::cout, std::endl, std::setw, std::setprecision;
  17. using ra::TestRecorder, ra::Benchmark, ra::Small, ra::ViewBig, ra::Unique;
  18. using Vec = ra::Small<float, 4>;
  19. int main()
  20. {
  21. TestRecorder tr(std::cout);
  22. tr.section("small vector ops through vector extensions, other types / sizes");
  23. {
  24. ra::Small<double, 4> a = 1 + ra::_0;
  25. ra::Small<double, 2, 4> b = 33 - ra::_1;
  26. auto c = optimize(a + b(1));
  27. tr.info("optimization of view").test(std::is_same_v<decltype(c), ra::Small<double, 4>>);
  28. tr.test_eq(34, c);
  29. }
  30. auto bench_type =
  31. [&](auto v)
  32. {
  33. using Vec = decltype(v);
  34. auto sum_opt =
  35. [&](auto & a, auto & b, auto & c)
  36. {
  37. for (int i=0; i<a.len(0); ++i) {
  38. c(i) = ra::optimize(a(i)+b(i));
  39. static_assert(std::is_same_v<decltype(optimize(a(i)+b(i))), Vec>); // making sure opt is on
  40. }
  41. };
  42. auto sum_unopt =
  43. [&](auto & a, auto & b, auto & c)
  44. {
  45. for (int i=0; i<a.len(0); ++i) {
  46. c(i) = a(i)+b(i);
  47. }
  48. };
  49. auto bench_all =
  50. [&](int reps, int m)
  51. {
  52. auto bench =
  53. [&tr, &m, &reps](auto && f, char const * tag)
  54. {
  55. // FIXME need alignment knobs for Big
  56. alignas (alignof(Vec)) Vec astore[m];
  57. alignas (alignof(Vec)) Vec bstore[m];
  58. alignas (alignof(Vec)) Vec cstore[m];
  59. ra::ViewBig<Vec, 1> a({m}, astore);
  60. ra::ViewBig<Vec, 1> b({m}, bstore);
  61. ra::ViewBig<Vec, 1> c({m}, cstore);
  62. a = +ra::_0 +1;
  63. b = -ra::_0 -1;
  64. c = 99;
  65. auto bv = Benchmark().repeats(reps).runs(3).run([&]() { f(a, b, c); });
  66. tr.info(std::setw(5), std::fixed, Benchmark::avg(bv)/(m)/1e-9, " ns [",
  67. Benchmark::stddev(bv)/(m)/1e-9 ,"] ", tag).test(true);
  68. };
  69. tr.section("[", (std::is_same_v<float, std::decay_t<decltype(std::declval<Vec>()[0])>> ? "float" : "double"),
  70. " x ", Vec::size(), "] block of ", m, " times ", reps);
  71. bench(sum_opt, "opt");
  72. bench(sum_unopt, "unopt");
  73. };
  74. bench_all(50000, 10);
  75. bench_all(50000, 100);
  76. bench_all(50000, 1000);
  77. };
  78. bench_type(ra::Small<float, 2> {});
  79. bench_type(ra::Small<double, 2> {});
  80. bench_type(ra::Small<float, 4> {});
  81. bench_type(ra::Small<double, 4> {});
  82. bench_type(ra::Small<float, 8> {});
  83. bench_type(ra::Small<double, 8> {});
  84. return tr.summary();
  85. }