forked from tututugege/GenSimpoint
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsimpoint.cpp
More file actions
215 lines (180 loc) · 6.18 KB
/
simpoint.cpp
File metadata and controls
215 lines (180 loc) · 6.18 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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#include "ref.h"
#include <cstdint>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <zlib.h>
// --- 辅助函数:简化 zlib 读写 POD 类型 ---
template <typename T> void gz_write_pod(gzFile file, const T &data) {
if (gzwrite(file, &data, sizeof(T)) != sizeof(T)) {
std::cerr << "Error writing data to gzip file." << std::endl;
exit(1);
}
}
template <typename T> void gz_read_pod(gzFile file, T &data) {
if (gzread(file, &data, sizeof(T)) != sizeof(T)) {
std::cerr << "Error reading data from gzip file." << std::endl;
exit(1);
}
}
void Ref_cpu::bbv_init_file(const char *filename) {
bbv_file.open(filename, std::ios::out | std::ios::trunc);
if (!bbv_file.is_open()) {
std::cerr << "Error: Could not open BBV output file!" << std::endl;
}
bbv_counts.resize(65536, 0);
}
void Ref_cpu::bbv_commit() {
// [ID 映射]:将 PC 转换为 SimPoint ID
uint32_t bb_id = 0;
auto it = global_pc_to_id.find(current_bb_head_pc);
if (it != global_pc_to_id.end()) {
bb_id = it->second; // 以前见过,用老 ID
} else {
bb_id = next_bb_id++; // 没见过,分配新 ID
global_pc_to_id[current_bb_head_pc] = bb_id;
}
if (bb_id >= bbv_counts.size()) {
// 策略:指数级扩容 (Geometric Growth)
// 比如每次扩大 2 倍,避免每次只加 1 导致频繁申请内存
// 如果 id 突然变得很大,至少要扩容到 id + 1
size_t new_size = bbv_counts.size() * 2;
if (new_size <= bb_id)
new_size = bb_id + 1024;
// resize 会自动把新增加的部分初始化为 0
bbv_counts.resize(new_size, 0);
}
// 3. [统计]:当前切片计数
bbv_counts[bb_id] += current_bb_len;
}
void Ref_cpu::dump_bbv() {
static int count = 0;
bbv_file << "T";
// 遍历 vector,只要非零的都输出
for (size_t id = 1; id < bbv_counts.size(); ++id) {
if (bbv_counts[id] > 0) {
bbv_file << ":" << id << ":" << bbv_counts[id];
bbv_counts[id] = 0; // 输出完清零,为下一轮做准备
}
}
bbv_file << "\n";
std::cout << "bbv dump:" << count++ << std::endl;
}
#include <iostream>
#include <string>
#include <zlib.h>
// 单次写入的安全块大小 (1GB)
const uint64_t GZ_CHUNK_SIZE = 1ULL * 1024 * 1024 * 1024;
void Ref_cpu::save_checkpoint(const std::string &filename) {
std::string final_name = filename;
if (final_name.size() < 3 ||
final_name.substr(final_name.size() - 3) != ".gz") {
final_name += ".gz";
}
gzFile file = gzopen(final_name.c_str(), "wb1"); // wb1 速度最快
if (!file) {
std::cerr << "Error: Could not open file: " << final_name << std::endl;
return;
}
// 1. 保存各种状态 (POD)
gz_write_pod(file, state);
gz_write_pod(file, interval_inst_count);
// 2. 保存内存 (关键修改)
if (ram_size > 0 && memory != nullptr) {
// [关键] ram_size 是 word 个数,需转换为字节数
// 必须强转为 uint64_t 防止乘法溢出
uint64_t total_bytes = (uint64_t)ram_size * sizeof(uint32_t);
uint8_t *byte_ptr = reinterpret_cast<uint8_t *>(memory);
uint64_t remain = total_bytes;
std::cout << "Saving Memory: " << ram_size << " words ("
<< (total_bytes / 1024 / 1024) << " MB)..." << std::endl;
while (remain > 0) {
// 每次最多写入 1GB,确保不超出 zlib 限制
unsigned int chunk = (remain > GZ_CHUNK_SIZE)
? (unsigned int)GZ_CHUNK_SIZE
: (unsigned int)remain;
int written = gzwrite(file, byte_ptr, chunk);
if (written <= 0) {
std::cerr << "Error: gzwrite failed." << std::endl;
break;
}
byte_ptr += chunk; // 指针按字节移动
remain -= chunk;
}
}
gzclose(file);
std::cout << "Checkpoint saved to " << final_name << std::endl;
}
void Ref_cpu::restore_checkpoint(const std::string &filename) {
std::string final_name = filename;
gzFile file = gzopen(final_name.c_str(), "rb");
if (!file && final_name.find(".gz") == std::string::npos) {
final_name += ".gz";
file = gzopen(final_name.c_str(), "rb");
}
if (!file) {
std::cerr << "Error: Could not open file: " << filename << std::endl;
exit(1);
}
// 1. 恢复状态
gz_read_pod(file, state);
gz_read_pod(file, interval_inst_count);
// 2. 恢复内存
if (memory == nullptr) {
std::cerr << "Error: Memory not allocated." << std::endl;
exit(1);
}
// [关键] 计算总字节数
uint64_t total_bytes = (uint64_t)ram_size * sizeof(uint32_t);
uint8_t *byte_ptr = reinterpret_cast<uint8_t *>(memory);
uint64_t remain = total_bytes;
std::cout << "Restoring Memory..." << std::endl;
while (remain > 0) {
unsigned int chunk = (remain > GZ_CHUNK_SIZE) ? (unsigned int)GZ_CHUNK_SIZE
: (unsigned int)remain;
int read_bytes = gzread(file, byte_ptr, chunk);
if (read_bytes < 0) {
std::cerr << "Error: gzread failed." << std::endl;
exit(1);
}
if (read_bytes == 0) {
std::cerr << "Error: Unexpected EOF." << std::endl;
exit(1);
}
byte_ptr += read_bytes;
remain -= read_bytes;
}
gzclose(file);
std::cout << "Checkpoint restored from " << final_name << std::endl;
}
// 辅助结构:记录 SimPoint ID 和 对应的 Interval ID
struct PointInfo {
uint32_t sp_id; // SimPoint ID (例如 0, 1, 2...)
uint32_t interval_id; // 对应的 Interval 编号 (例如 105, 2000...)
};
std::map<uint32_t, uint32_t> load_simpoints(const std::string &filename) {
std::map<uint32_t, uint32_t> targets;
std::ifstream in(filename);
if (!in) {
std::cerr << "Error: Could not open points file: " << filename << std::endl;
exit(1);
}
std::string line;
while (std::getline(in, line)) {
// 跳过空行和注释
if (line.empty() || line[0] == '#')
continue;
std::stringstream ss(line);
uint32_t interval_id, sp_id;
// data format: <Interval_ID> <SimPoint_ID>
// Example: 1824 0
if (ss >> interval_id >> sp_id) {
targets[interval_id] = sp_id;
// 调试输出,确保读入正确
std::cout << "Target: Interval " << interval_id << " -> SP " << sp_id
<< std::endl;
}
}
return targets;
}