-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathcore.cc
100 lines (81 loc) · 2.98 KB
/
core.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
#include <exception>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <boost/timer/timer.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/multi_array/multi_array_ref.hpp>
#include "mapping.h"
#include "mincore.h"
#include "blob.h"
#include "access.h"
const constexpr auto kMaxRuns = 10u;
template <typename Iter>
void run_access(const char* pattern, Iter first, Iter last) {
using namespace std::string_literals;
std::string result;
if (pattern == "seq"s) {
boost::timer::cpu_timer accessing;
for (auto idx = kMaxRuns; idx != 0; --idx)
access_seq(first, last);
accessing.stop();
result = accessing.format();
} else if (pattern == "rnd"s) {
boost::timer::cpu_timer accessing;
for (auto idx = kMaxRuns; idx != 0; --idx)
access_rnd(first, last);
accessing.stop();
result = accessing.format();
} else {
std::fprintf(stderr, "Error: invalid access pattern: %s\n", pattern);
return;
}
std::printf("Accessing: %s", result.c_str());
}
inline void usage(const char* path) { std::fprintf(stderr, "Usage: %s [ heap | mmap ] [ seq | rnd ] path\n", path); }
int main(int argc, char** argv) try {
if (argc != 4) {
usage(argv[0]);
return EXIT_FAILURE;
}
const auto memory_type = argv[1];
const auto access_pattern = argv[2];
const boost::filesystem::path path(argv[3]);
if (not boost::filesystem::exists(path)) {
std::printf("Dumping to %s\n", path.c_str());
dump_to_binary(path.string().c_str());
}
using namespace std::string_literals;
if (memory_type == "heap"s) {
// 1/ read from file into heap
boost::timer::cpu_timer loading;
const auto vec = read_from_binary(path.c_str());
// const auto vec = read_from_binary_through_stream(path.c_str());
const auto first = vec.data();
const auto last = vec.data() + vec.size();
loading.stop();
std::printf("Loading: %s", loading.format().c_str());
run_access(access_pattern, first, last);
} else if (memory_type == "mmap"s) {
// 2/ read directly through mmaped region
boost::timer::cpu_timer loading;
const auto region = make_mapping(path.c_str());
const auto first = static_cast<const Blob*>(region.get_address());
const auto bytes = region.get_size();
const auto last = first + (bytes / sizeof(Blob));
loading.stop();
std::printf("Loading: %s", loading.format().c_str());
run_access(access_pattern, first, last);
// Non-owning one-dimensional array_view wrapper around a memory range; iteratable, size, data, etc.
// http://www.boost.org/doc/libs/1_60_0/libs/multi_array/doc/reference.html#const_multi_array_ref
// boost::const_multi_array_ref<Blob, 1> array_view{first, boost::extents[last - first]};
} else {
std::fprintf(stderr, "Error: invalid memory type %s\n", memory_type);
usage(argv[0]);
return EXIT_FAILURE;
}
} catch (const std::exception& e) {
std::fprintf(stderr, "Error: %s\n", e.what());
return EXIT_FAILURE;
}