-
Notifications
You must be signed in to change notification settings - Fork 3
/
gspin_patterns.cpp
261 lines (196 loc) · 6.29 KB
/
gspin_patterns.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
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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
#include <stdio.h>
#include <stdlib.h>
#include <zlib.h>
#include <stdexcept>
#include <iostream>
#include <sstream>
#include <string>
#include <exception>
#include "gs_patterns.h"
#include "gs_patterns_core.h"
#include "gspin_patterns.h"
#include "utils.h"
namespace gs_patterns
{
namespace gspin_patterns
{
using namespace gs_patterns::gs_patterns_core;
int drline_read(gzFile fp, trace_entry_t * val, trace_entry_t ** p_val, int * edx)
{
int idx;
idx = (*edx) / sizeof(trace_entry_t);
//first read
if (NULL == *p_val) {
*edx = gzread(fp, val, sizeof(trace_entry_t) * NBUFS);
*p_val = val;
} else if (*p_val == &val[idx]) {
*edx = gzread(fp, val, sizeof(trace_entry_t) * NBUFS);
*p_val = val;
}
if (0 == *edx)
return 0;
return 1;
}
Metrics & MemPatternsForPin::get_metrics(mem_access_type m)
{
switch (m)
{
case GATHER : return _metrics.first;
case SCATTER : return _metrics.second;
default:
throw GSError("Unable to get Metrics - Invalid Metrics Type: " + std::to_string(m));
}
}
InstrInfo & MemPatternsForPin::get_iinfo(mem_access_type m)
{
switch (m)
{
case GATHER : return _iinfo.first;
case SCATTER : return _iinfo.second;
default:
throw GSError("Unable to get InstrInfo - Invalid Metrics Type: " + std::to_string(m));
}
}
void MemPatternsForPin::handle_trace_entry(const InstrAddrAdapter & ia)
{
// Call libgs_patterns
gs_patterns_core::handle_trace_entry(*this, ia);
}
void MemPatternsForPin::generate_patterns()
{
// ----------------- Update Source Lines -----------------
//update_source_lines();
// ----------------- Update Metrics -----------------
update_metrics();
// ----------------- Create Spatter File -----------------
create_spatter_file<MEMORY_ACCESS_SIZE>(*this, get_file_prefix());
}
void MemPatternsForPin::update_metrics()
{
gzFile fp_drtrace;
try
{
fp_drtrace = open_trace_file(get_trace_file_name());
}
catch (const std::runtime_error & ex)
{
throw GSFileError(ex.what());
}
// Get top gathers
get_gather_metrics().ntop = get_top_target(get_gather_iinfo(), get_gather_metrics());
// Get top scatters
get_scatter_metrics().ntop = get_top_target(get_scatter_iinfo(), get_scatter_metrics());
// ----------------- Second Pass -----------------
process_second_pass(fp_drtrace);
// ----------------- Normalize -----------------
normalize_stats(get_gather_metrics());
normalize_stats(get_scatter_metrics());
close_trace_file(fp_drtrace);
}
std::string MemPatternsForPin::get_file_prefix()
{
std::string prefix = _trace_file_name;
size_t pos = std::string::npos;
while (std::string::npos != (pos = prefix.find(".gz")))
{
prefix.replace(pos, 3, "");
}
return prefix;
}
double MemPatternsForPin::update_source_lines_from_binary(mem_access_type mType)
{
double target_cnt = 0.0;
InstrInfo & target_iinfo = get_iinfo(mType);
Metrics & target_metrics = get_metrics(mType);
//Check it is not a library
for (int k = 0; k < NGS; k++) {
if (0 == target_iinfo.get_iaddrs()[k]) {
break;
}
#if SYMBOLS_ONLY
translate_iaddr(get_binary_file_name(), target_metrics.get_srcline()[k], target_iinfo.get_iaddrs()[k]);
if (startswith(target_metrics.get_srcline()[k], "?")) {
target_iinfo.get_icnt()[k] = 0;
target_metrics.iaddrs_nosym++;
target_metrics.indices_nosym += target_iinfo.get_occ()[k];
} else {
target_metrics.iaddrs_sym++;
target_metrics.indices_sym += target_iinfo.get_occ()[k];
}
#endif
target_cnt += target_iinfo.get_icnt()[k];
}
printf("done.\n");
return target_cnt;
}
// First Pass
void MemPatternsForPin::process_traces()
{
int iret = 0;
trace_entry_t *drline;
gzFile fp_drtrace;
try
{
fp_drtrace = open_trace_file(get_trace_file_name());
}
catch (const std::runtime_error & ex)
{
throw GSFileError(ex.what());
}
printf("First pass to find top gather / scatter iaddresses\n");
fflush(stdout);
uint64_t lines_read = 0;
trace_entry_t *p_drtrace = NULL;
trace_entry_t drtrace[NBUFS]; // was static (1024 bytes)
while (drline_read(fp_drtrace, drtrace, &p_drtrace, &iret)) {
//decode drtrace
drline = p_drtrace;
handle_trace_entry(InstrAddrAdapterForPin(drline));
p_drtrace++;
lines_read++;
}
std::cout << "Lines Read: " << lines_read << std::endl;
close_trace_file(fp_drtrace);
//metrics
get_trace_info().gather_occ_avg /= get_gather_metrics().cnt;
get_trace_info().scatter_occ_avg /= get_scatter_metrics().cnt;
// ----------------- Update Source Lines -----------------
update_source_lines();
display_stats<MEMORY_ACCESS_SIZE>(*this);
}
void MemPatternsForPin::process_second_pass(gzFile & fp_drtrace)
{
uint64_t mcnt = 0; // used our own local mcnt while iterating over file in this method.
int iret = 0;
trace_entry_t *drline;
// State carried thru
addr_t iaddr;
int64_t maddr;
addr_t gather_base[NTOP] = {0};
addr_t scatter_base[NTOP] = {0};
bool breakout = false;
printf("\nSecond pass to fill gather / scatter subtraces\n");
fflush(stdout);
trace_entry_t *p_drtrace = NULL;
trace_entry_t drtrace[NBUFS]; // was static (1024 bytes)
while (drline_read(fp_drtrace, drtrace, &p_drtrace, &iret) && !breakout) {
//decode drtrace
drline = p_drtrace;
breakout = handle_2nd_pass_trace_entry(InstrAddrAdapterForPin(drline), get_gather_metrics(), get_scatter_metrics(),
iaddr, maddr, mcnt, gather_base, scatter_base);
p_drtrace++;
}
}
void MemPatternsForPin::update_source_lines()
{
// Find source lines for gathers - Must have symbol
printf("\nSymbol table lookup for gathers...");
fflush(stdout);
get_gather_metrics().cnt = update_source_lines_from_binary(GATHER);
// Find source lines for scatters
printf("Symbol table lookup for scatters...");
fflush(stdout);
get_scatter_metrics().cnt = update_source_lines_from_binary(SCATTER);
}
} // namespace gspin_patterns
} // namespace gs_patterns