-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathmain.cc
More file actions
124 lines (114 loc) · 4.08 KB
/
main.cc
File metadata and controls
124 lines (114 loc) · 4.08 KB
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
119
120
121
122
123
124
#include "def.hh"
#include "dramsim3_interface.hh"
#include "requester.hh"
#include "xerxes_standalone.hh"
#include <chrono>
#include <fstream>
#include <iostream>
using namespace std;
int main(int argc, char *argv[]) {
// Initialize a global simulation object.
auto sim = xerxes::Simulation{};
xerxes::init_sim(&sim);
// Parse the TOML configuration file.
std::string config_file = "";
if (argc > 1)
config_file = argv[1];
else
config_file = "configs/test.toml";
// check if the file exists
std::ifstream f(config_file);
if (!f.good()) {
std::cerr << "File " << config_file << " does not exist." << std::endl;
return 1;
}
std::cout << "Config file: " << config_file << std::endl;
auto ctx = xerxes::parse_config(config_file);
auto fout = std::fstream(ctx.general.log_name, std::ios::out);
// Set packet logger, which logs the latency components of each request.
xerxes::set_pkt_logger(fout,
xerxes::str_to_log_level(ctx.general.log_level));
auto &config = ctx.general;
auto &requesters = ctx.requesters;
auto &mems = ctx.mems;
// Run the simulation.
std::cout << "Start simulation." << std::endl;
for (auto &requester : requesters)
requester->register_issue_event(0);
xerxes::Tick clock_cnt = 0;
xerxes::Tick last_curt = INT_MAX;
// Helper functions to check whether all requesters have issued
// all their requests.
auto check_all_issued = [&requesters]() {
for (auto &requester : requesters) {
if (!requester->all_issued()) {
return false;
}
}
return true;
};
// Helper function to check whether all requesters' queues are empty.
// If true, expect that all requests are finished.
auto check_all_empty = [&requesters]() {
for (auto &requester : requesters) {
if (!requester->q_empty()) {
return false;
}
}
return true;
};
std::vector<xerxes::Tick> mems_tick(mems.size(), 0);
// Ticking all memories and synchronizing them to the current tick.
auto clock_all_mems_to_tick = [&mems, &mems_tick, &config](
xerxes::Tick tick, bool not_changed) {
for (size_t i = 0; i < mems.size(); ++i)
mems_tick[i] = 0;
for (size_t i = 0; i < mems.size(); ++i) {
for (int g = 0;
g < config.clock_granu && (mems_tick[i] < tick || not_changed);
++g) {
mems_tick[i] = mems[i]->clock();
}
}
};
// Simulation.
auto start = std::chrono::high_resolution_clock::now();
while (clock_cnt < config.max_clock) {
if (check_all_issued()) {
break;
}
// current tick
auto curt = xerxes::step();
bool not_changed = last_curt == curt;
last_curt = curt;
// TODO: automate clock align.
clock_all_mems_to_tick(curt, not_changed);
clock_cnt++;
}
while (clock_cnt < config.max_clock) {
auto curt = xerxes::step();
bool not_changed = last_curt == curt;
last_curt = curt;
clock_all_mems_to_tick(curt, not_changed);
clock_cnt++;
if (check_all_empty()) {
break;
}
if (clock_cnt % 10000 == 0) {
auto end = std::chrono::high_resolution_clock::now();
auto duration =
std::chrono::duration_cast<std::chrono::milliseconds>(end -
start);
std::cout << "Clock: " << clock_cnt
<< " Duration: " << duration.count() << " ms"
<< std::endl;
}
}
auto end = std::chrono::high_resolution_clock::now();
auto duration =
std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "Simulation finished." << std::endl;
std::cout << "Duration: " << duration.count() << " ms" << std::endl;
xerxes::log_stats(std::cerr);
return 0;
}