ChampSim
tracereader.h
Go to the documentation of this file.
1 /*
2  * Copyright 2023 The ChampSim Contributors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef TRACEREADER_H
18 #define TRACEREADER_H
19 
20 #include <cstring>
21 #include <deque>
22 #include <memory>
23 #include <numeric>
24 #include <string>
25 
26 #include "instruction.h"
27 #include "util/detect.h"
28 
29 namespace champsim
30 {
32 {
33  static uint64_t instr_unique_id;
34  struct reader_concept {
35  virtual ~reader_concept() = default;
36  virtual ooo_model_instr operator()() = 0;
37  virtual bool eof() const = 0;
38  };
39 
40  template <typename T>
41  struct reader_model final : public reader_concept {
43  reader_model(T&& val) : intern_(std::move(val)) {}
44 
45  template <typename U>
46  using has_eof = decltype(std::declval<U>().eof());
47 
48  ooo_model_instr operator()() override { return intern_(); }
49  bool eof() const override
50  {
51  if constexpr (champsim::is_detected_v<has_eof, T>)
52  return intern_.eof();
53  return false; // If an eof() member function is not provided, assume the trace never ends.
54  }
55  };
56 
57  std::unique_ptr<reader_concept> pimpl_;
58 
59 public:
60  template <typename T>
61  tracereader(T&& val) : pimpl_(std::make_unique<reader_model<T>>(std::move(val)))
62  {
63  }
64 
65  auto operator()()
66  {
67  auto retval = (*pimpl_)();
68  retval.instr_id = instr_unique_id++;
69  return retval;
70  }
71 
72  auto eof() const { return pimpl_->eof(); }
73 };
74 
75 template <typename T, typename F>
77 {
78  static_assert(std::is_trivial_v<T>);
79  static_assert(std::is_standard_layout_v<T>);
80 
81  uint8_t cpu;
82  bool eof_ = false;
84 
85  constexpr static std::size_t buffer_size = 128;
86  constexpr static std::size_t refresh_thresh = 1;
87  std::deque<ooo_model_instr> instr_buffer;
88 
89 public:
91 
92  bulk_tracereader(uint8_t cpu_idx, std::string tf) : cpu(cpu_idx), trace_file(tf) {}
93  bulk_tracereader(uint8_t cpu_idx, F&& file) : cpu(cpu_idx), trace_file(std::move(file)) {}
94 
95  bool eof() const { return trace_file.eof() && std::size(instr_buffer) <= refresh_thresh; }
96 };
97 
99 
100 template <typename It>
101 void set_branch_targets(It begin, It end)
102 {
103  std::reverse_iterator rbegin{end}, rend{begin};
104  std::adjacent_difference(rbegin, rend, rbegin, apply_branch_target);
105 }
106 
107 template <typename T, typename F>
109 {
110  if (std::size(instr_buffer) <= refresh_thresh) {
111  std::array<T, buffer_size - refresh_thresh> trace_read_buf;
112  std::array<char, std::size(trace_read_buf) * sizeof(T)> raw_buf;
113  std::size_t bytes_read;
114 
115  // Read from trace file
116  trace_file.read(std::data(raw_buf), std::size(raw_buf));
117  bytes_read = static_cast<std::size_t>(trace_file.gcount());
118  eof_ = trace_file.eof();
119 
120  // Transform bytes into trace format instructions
121  std::memcpy(std::data(trace_read_buf), std::data(raw_buf), bytes_read);
122 
123  // Inflate trace format into core model instructions
124  auto begin = std::begin(trace_read_buf);
125  auto end = std::next(begin, bytes_read / sizeof(T));
126  std::transform(begin, end, std::back_inserter(instr_buffer), [cpu = this->cpu](T t) { return ooo_model_instr{cpu, t}; });
127 
128  // Set branch targets
129  set_branch_targets(std::begin(instr_buffer), std::end(instr_buffer));
130  }
131 
132  auto retval = instr_buffer.front();
133  instr_buffer.pop_front();
134 
135  return retval;
136 }
137 
138 std::string get_fptr_cmd(std::string_view fname);
139 } // namespace champsim
140 
141 champsim::tracereader get_tracereader(std::string fname, uint8_t cpu, bool is_cloudsuite, bool repeat);
142 
143 #endif
Definition: tracereader.h:77
F trace_file
Definition: tracereader.h:83
bulk_tracereader(uint8_t cpu_idx, std::string tf)
Definition: tracereader.h:92
bulk_tracereader(uint8_t cpu_idx, F &&file)
Definition: tracereader.h:93
bool eof_
Definition: tracereader.h:82
constexpr static std::size_t buffer_size
Definition: tracereader.h:85
std::deque< ooo_model_instr > instr_buffer
Definition: tracereader.h:87
bool eof() const
Definition: tracereader.h:95
constexpr static std::size_t refresh_thresh
Definition: tracereader.h:86
uint8_t cpu
Definition: tracereader.h:78
ooo_model_instr operator()()
Definition: tracereader.h:108
Definition: tracereader.h:32
std::unique_ptr< reader_concept > pimpl_
Definition: tracereader.h:57
auto eof() const
Definition: tracereader.h:72
auto operator()()
Definition: tracereader.h:65
tracereader(T &&val)
Definition: tracereader.h:61
static uint64_t instr_unique_id
Definition: tracereader.h:33
Definition: champsim.h:24
void set_branch_targets(It begin, It end)
Definition: tracereader.h:101
ooo_model_instr apply_branch_target(ooo_model_instr branch, const ooo_model_instr &target)
Definition: tracereader.cc:29
std::string get_fptr_cmd(std::string_view fname)
Definition: tracereader.h:34
virtual ooo_model_instr operator()()=0
Definition: tracereader.h:41
reader_model(T &&val)
Definition: tracereader.h:43
decltype(std::declval< U >().eof()) has_eof
Definition: tracereader.h:46
T intern_
Definition: tracereader.h:42
ooo_model_instr operator()() override
Definition: tracereader.h:48
bool eof() const override
Definition: tracereader.h:49
Definition: instruction.h:41
champsim::tracereader get_tracereader(std::string fname, uint8_t cpu, bool is_cloudsuite, bool repeat)
Definition: tracereader.cc:56