/
main.cpp
114 lines (97 loc) · 3.2 KB
/
main.cpp
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
#include <algorithm>
#include <chrono>
#include <cmath>
#include <cstddef>
#include <iostream>
#include <xtensor/xfixed.hpp>
#include <xtensor/xnoalias.hpp>
#include <xtensor/xtensor.hpp>
#include <xtensor/xrandom.hpp>
#include <xtensor/xvectorize.hpp>
// Simple stopwatch object
class stopwatch
{
public:
stopwatch() : m_start(clock_type::now())
{
}
void reset()
{
m_start = clock_type::now();
}
std::size_t elapsed() const
{
return std::chrono::duration_cast<std::chrono::nanoseconds>(clock_type::now() - m_start).count();
}
private:
typedef std::chrono::high_resolution_clock clock_type;
std::chrono::time_point<clock_type> m_start;
};
template <class T>
using xpoint = xt::xtensor_fixed<T, xt::xshape<3>>;
template <class T>
auto sum_xpoint(const xpoint<T>& t)
{
return std::accumulate(t.cbegin(), t.cend(), T());
}
// Simple test program
int main()
{
// First Benchmark:
//
// a[1000x1000] + b[1000] - sin(c[])
{
xt::xtensor<double, 2> a = xt::random::rand<double>({1000, 1000});
xt::xtensor<double, 1> b = xt::random::rand<double>({1000});
double c = 1.0;
// Un-evaluated broadcasting exprression
auto expr = a + b - std::sin(c);
auto res = xt::xtensor<double, 2>::from_shape({1000, 1000});
// Benchmark loop
std::cout << "Benchmarking a[1000x1000] + b[1000] - sin(c[])" << std::endl;
std::size_t min_time = 100000000;
for (int i = 0; i < 200; ++i)
{
stopwatch timer; // Create timer
xt::noalias(res) = expr; // Evaluate the expression.
auto elapsed = timer.elapsed(); // Nanoseconds
if (elapsed < min_time)
{
min_time = elapsed;
}
}
// Output results
std::cout << "MIN TIME: " << min_time << " ns" << std::endl;
std::cout << " = " << (double) min_time / (double) 1000 << " μs" << std::endl;
std::cout << std::endl << std::endl;
}
// Second Benchmark:
//
// std::sqrt(sum(a * b));
{
constexpr std::size_t psz = 1000000;
auto px = xt::xtensor<xpoint<float>, 1>({psz}, {0.5f, 2.1f, 3.2f}),
py = xt::xtensor<xpoint<float>, 1>({psz}, {0.5f, 2.1f, 3.2f});
auto res = xt::xtensor<float, 1>({psz});
auto sum = xt::vectorize(sum_xpoint<float>);
// Un-evaluated broadcasting expression
auto expr = xt::sqrt(sum(px * py));
// Benchmark loop
std::cout << "Benchmarking sqrt(sum(a * b))" << std::endl;
std::size_t min_time = 100000000;
for (int i = 0; i < 200; ++i)
{
stopwatch timer; // Create timer
xt::noalias(res) = expr; // Evaluate the expression.
auto elapsed = timer.elapsed(); // Nanoseconds
if (elapsed < min_time)
{
min_time = elapsed;
}
}
// Output results
std::cout << "MIN TIME: " << min_time << " ns" << std::endl;
std::cout << " = " << (double) min_time / (double) 1000 << " μs" << std::endl;
std::cout << std::endl << std::endl;
}
}