-
Notifications
You must be signed in to change notification settings - Fork 5
/
bench-at.cc
118 lines (107 loc) · 3.41 KB
/
bench-at.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// -*- mode: c++; coding: utf-8 -*-
// ra-ra/bench - Benchmark for at() operator.
// (c) Daniel Llorens - 2023
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License as published by the Free
// Software Foundation; either version 3 of the License, or (at your option) any
// later version.
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include "ra/test.hh"
using std::cout, std::endl, std::flush, ra::TestRecorder;
using real = double;
using ra::dim_t;
// FIXME Bigd/Bigd at loop is an outlier
int main()
{
ra::TestRecorder tr(std::cout);
auto test = [&tr](auto && C, auto && I, int reps)
{
int M = C.len(0);
int N = C.len(1);
int O = I.len(0);
C = 4*ra::_0 + ra::_1;
I(ra::all, 0) = map([&](auto && i) { return i%M; }, ra::_0 + (std::rand() & 1));
I(ra::all, 1) = map([&](auto && i) { return i%N; }, ra::_0 + (std::rand() & 1));
int ref0 = sum(at(C, iter<1>(I))), val0 = 0;
ra::Benchmark bm { reps, 3 };
auto report = [&](std::string const & tag, auto && bv)
{
tr.info(std::setw(5), std::fixed, bm.avg(bv)/M/N/1e-9, " ns [", bm.stddev(bv)/M/N/1e-9, "] ", tag)
.test_eq(val0, ref0);
};
report("direct subscript",
bm.run([&] {
int val = 0;
for (int i=0; i<O; ++i) {
val += C(dim_t(I(i, 0)), dim_t(I(i, 1))); // conversions needed when I has runtime rank
}
val0 = val;
}));
report("at member + loop",
bm.run([&] {
int val = 0;
for (int i=0; i<O; ++i) {
val += C.at(I(i));
}
val0 = val;
}));
report("at op + iter",
bm.run([&] {
val0 = sum(at(C, iter<1>(I)));
}));
};
tr.section("Bigs/Bigs");
{
ra::Big<int, 2> C({1000, 4}, ra::none);
ra::Big<int, 2> I({1000, 2}, ra::none);
test(C, I, 100);
}
tr.section("Bigd/Bigd");
{
ra::Big<int> C({1000, 4}, ra::none);
ra::Big<int> I({1000, 2}, ra::none);
test(C, I, 100);
}
// regression in b40c2d412be04c4c2b4758a332424c05257f71ff due to CellSmall copy ctor.
tr.section("Small/Small");
{
ra::Small<int, 10, 4> C;
ra::Small<int, 10, 2> I;
test(C, I, 10000);
}
tr.section("Bigd/Bigs");
{
ra::Big<int> C({1000, 4}, ra::none);
ra::Big<int, 2> I({1000, 2}, ra::none);
test(C, I, 100);
}
tr.section("Bigs/Bigd");
{
ra::Big<int, 2> C({1000, 4}, ra::none);
ra::Big<int> I({1000, 2}, ra::none);
test(C, I, 100);
}
tr.section("Bigs/Small");
{
ra::Big<int, 2> C({1000, 4}, ra::none);
ra::Small<int, 10, 2> I;
test(C, I, 1000);
}
tr.section("Bigd/Small");
{
ra::Big<int> C({1000, 4}, ra::none);
ra::Small<int, 10, 2> I;
test(C, I, 1000);
}
// FIXME not supported atm bc small.at output type depends on the length of the subscript.
// tr.section("Small/Bigs");
// {
// ra::Small<int, 10, 4> C;
// ra::Big<int, 2> I({1000, 2}, ra::none);
// test(C, I, 1000);
// }
return tr.summary();
}