OpenCores
URL https://opencores.org/ocsvn/igor/igor/trunk

Subversion Repositories igor

[/] [igor/] [trunk/] [simulator/] [profiler.c] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 atypic
#include <malloc.h>
2
#include <err.h>
3
#include <math.h>
4
 
5
#include "types.h"
6
#include "microcode.h"
7
#include "instructions.h"
8
#include "object.h"
9
#include "profiler.h"
10
#include "memory.h"
11
#include <string.h>
12
#include "io.h"
13
 
14
unsigned int *instruction_executions;
15
 
16
profile_t profile;
17
cache_t cache;
18
int profile_number;
19
 
20
/* Initialize a profil^W simulator structure */
21
void sim_init(char* name, int microprogram_size, int cache_size, unsigned int mem_size, unsigned int branch_buffer_size, char * branch_pred_scheme)
22
{
23
//      if(p == NULL)
24
//              p = &profile;
25
 
26
 
27
        profile.branch_buffer = calloc(branch_buffer_size, sizeof(int));
28
        profile.reuse = calloc(mem_size, sizeof(int));
29
        profile.reuse_sum = calloc(mem_size, sizeof(long long int));
30
        profile.instruction_execs = calloc(microprogram_size, sizeof(long long int));
31
        profile.memory_access = calloc(mem_size, sizeof(long long int));
32
        printf("initialized memory to %d\n", mem_size);
33
        cache_init(&cache, cache_size);
34
 
35
        profile.name = strdup(name);
36
        profile.mp_size = microprogram_size;
37
        profile.memory_size = mem_size;
38
        profile.total_execs = 0;
39
        profile.cache = &cache;
40
        /* branches */
41
        profile.branch_buffer_size = branch_buffer_size;
42
 
43
        profile.br_predict = 0;
44
        profile.br_mispredict = 0;
45
        profile.branch_pred_scheme = branch_pred_scheme;
46
 
47
        //profile.num_per_type = calloc(NUM_INSTRUCTIONS, sizeof(int));
48
        int i;
49
        for(i=0;i < NUM_INSTRUCTIONS; i++) { profile.num_per_type[i] = 0; }
50
 
51
        /* OK! */
52
        profile.initialized = 1;
53
}
54
 
55
 
56
void
57
profiler_init(int microprogram_size,  int cache_size)
58
{
59
        int i;
60
        profile.instruction_execs = calloc(microprogram_size, sizeof(int));
61
        profile.total_execs = 0;
62
        profile.mp_size = microprogram_size;
63
        for(i = 0; i < NUM_INSTRUCTIONS; i++) { profile.num_per_type[i] = 0; }
64
        cache_init(&cache, cache_size);
65
        profile_number = 0;
66
 
67
        profile.memory_size = DEFAULT_MEMORY_SIZE;
68
 
69
        /* Initialize memory */
70
        profile.memory_access = calloc(DEFAULT_MEMORY_SIZE, sizeof(int));
71
        /* Last re-use time for memory addresses */
72
        profile.reuse = calloc(DEFAULT_MEMORY_SIZE, sizeof(int));
73
        /* Sum of reuse-times for all memory addresses */
74
        profile.reuse_sum = calloc(DEFAULT_MEMORY_SIZE, sizeof(int));
75
}
76
 
77
void
78
profiler_new()
79
{
80
        profile_number++;
81
        memset(profile.instruction_execs, 0, profile.mp_size);
82
        profile.total_execs = 0;
83
        memset(profile.num_per_type, 0, NUM_INSTRUCTIONS);
84
 
85
        profile.cache->hits = 0;
86
        profile.cache->misses = 0;
87
        memset(profile.cache->storage, 0, profile.cache->size);
88
 
89
}
90
 
91
 
92
void
93
profiler_add_execution(unsigned int addr, instr_t instr, int flags)
94
{
95
        if(profile.initialized != 1) { return; }
96
 
97
        profile.instruction_execs[addr]++;
98
        profile.total_execs++;
99
        //uint32_t ls;
100
        int32_t ls = 0;
101
 
102
        //Add to type-count.
103
        profile.num_per_type[instr.op]++;
104
        switch(instr.op) {
105
                case INS_STORE:
106
                        break;
107
                case INS_LOAD:
108
 
109
                        ls = (OBJECT_DATUM(instr_get_reg(instr.r2))+instr.disp);
110
                        if ((ls & IO_AREA_MASK) == IO_AREA_MASK) {
111
                                break;
112
                        }
113
                        cache_load(profile.cache, ls);
114
                        profile.memory_access[ls]++;
115
                        reuse_update(&profile, ls);
116
                        break;
117
                case INS_BRANCH:
118
                case INS_BRANCH_REG:
119
                        if(0 == strcmp(profile.branch_pred_scheme, "taken")) {
120
                                if ((instr.flag_mask & flags) == instr.flag_values) {
121
                                        profile.br_predict++;
122
                                } else {
123
                                        profile.br_mispredict++;
124
                                }
125
                        } else if(0 == strcmp(profile.branch_pred_scheme, "2bit")) {
126
 
127
                                //int branch_entry = addr%profile.branch_buffer_size;
128
                                int branch_entry = (unsigned int)addr%(unsigned int)profile.branch_buffer_size;
129
 
130
                                if(profile.branch_buffer[branch_entry] == PREDICT_TAKEN_1) {
131
                                        if ((instr.flag_mask & flags) == instr.flag_values) {
132
                                                profile.br_predict++;
133
                                                profile.branch_buffer[branch_entry] = PREDICT_TAKEN_1;
134
                                        } else {
135
                                                profile.branch_buffer[branch_entry] = PREDICT_TAKEN_2;
136
                                                profile.br_mispredict++;
137
                                        }
138
                                } else if(profile.branch_buffer[branch_entry] == PREDICT_TAKEN_2) {
139
                                        if ((instr.flag_mask & flags) == instr.flag_values) {
140
                                                profile.br_predict++;
141
                                                profile.branch_buffer[branch_entry] = PREDICT_TAKEN_1;
142
                                        } else {
143
                                                profile.branch_buffer[branch_entry] = PREDICT_NOT_TAKEN_1;
144
                                                profile.br_mispredict++;
145
                                        }
146
                                } else if(profile.branch_buffer[branch_entry] == PREDICT_NOT_TAKEN_1) {
147
                                                if ((instr.flag_mask & flags) == instr.flag_values) {
148
                                                        profile.branch_buffer[branch_entry] = PREDICT_TAKEN_1;
149
                                                        profile.br_mispredict++;
150
                                                } else {
151
                                                        profile.br_predict++;
152
                                                        profile.branch_buffer[branch_entry] = PREDICT_NOT_TAKEN_1;
153
                                                }
154
                                } else if(profile.branch_buffer[branch_entry] == PREDICT_NOT_TAKEN_2) {
155
                                        if ((instr.flag_mask & flags) == instr.flag_values) {
156
                                                profile.branch_buffer[branch_entry] = PREDICT_TAKEN_1;
157
                                                profile.br_mispredict++;
158
                                        } else {
159
                                                profile.br_predict++;
160
                                                profile.branch_buffer[branch_entry] = PREDICT_NOT_TAKEN_1;
161
                                        }
162
                                }
163
                        }
164
                        break;
165
                default:
166
                        break;
167
        }
168
 
169
 
170
        if (profile.total_execs==0) {
171
                errx(1, "instruction count overflow\n");
172
        }
173
}
174
 
175
 
176
void reuse_update(profile_t* p, unsigned int addr)
177
{
178
        int sample = abs(p->total_execs - p->reuse[addr]);
179
        p->reuse[addr] = p->total_execs;
180
        p->reuse_sum[addr] += sample;
181
}
182
 
183
 
184
void
185
profiler_dump_program(char* filename)
186
{
187
//      char filename[50];
188
 
189
//      sprintf(filename, "profile_%d.txt", profile_number);
190
 
191
        if(profile.initialized != 1) return;
192
        sim_write_file(&profile, filename);
193
        return;
194
}
195
 
196
 
197
 
198
 
199
 
200
/*----------------------------*/
201
/* - File writing functions - */
202
/*----------------------------*/
203
 
204
void sim_write_file(profile_t* p, const char* filename)
205
{
206
        if(filename == NULL) {
207
                errx(1, "no filename in write_profiler_file\n");
208
        }
209
 
210
        printf("Writing simulation data to disk.\n");
211
        FILE* f = fopen(filename, "w");
212
        sim_write_global_info(p, f);
213
        sim_write_cache_info(p, f);
214
        sim_write_branch_counts(p, f);
215
        sim_write_instr_counts(p, f);
216
        sim_write_reuse_info(p, f);
217
        sim_write_mem_count(p, f);
218
        sim_write_mc_info(p, f);
219
        fclose(f);
220
}
221
 
222
void sim_write_global_info(profile_t* p, FILE* f)
223
{
224
        printf("Global information\n");
225
        fprintf(f, "[NAME]\n");
226
        fprintf(f, "%s\n", p->name);
227
        fprintf(f, "[TOTAL_EXECS]\n");
228
        fprintf(f, "%llu\n", p->total_execs);
229
}
230
 
231
void sim_write_cache_info(profile_t* p, FILE* f)
232
{
233
        printf("Writing cache info\n");
234
        fprintf(f, "[CACHESIZE]\n %u\n", p->cache->size);
235
        fprintf(f, "[CACHEHITS]\n %u\n", p->cache->hits);
236
        fprintf(f, "[CACHEMISS]\n %u\n", p->cache->misses);
237
}
238
 
239
void sim_write_reuse_info(profile_t* p, FILE* f)
240
{
241
        printf("Writing reuse times for memsize %d\n",p->memory_size);
242
        int i;
243
        fprintf(f, "[REUSE]\n");
244
        for (i = 0; i < p->memory_size; i++) {
245
                fprintf(f, "0x%08X %d %llu\n", i, p->reuse_sum[i], p->memory_access[i]);
246
        }
247
}
248
 
249
void sim_write_mem_count(profile_t* p, FILE* f)
250
{
251
        printf("Writing memory hit counts\n");
252
        int i;
253
        fprintf(f, "[MEMCOUNT]\n");
254
        for (i = 0; i < p->memory_size; i++) {
255
                fprintf(f, "0x%08X %llu\n", i, p->memory_access[i]);
256
        }
257
}
258
 
259
void sim_write_mc_info(profile_t* p, FILE* f)
260
{
261
        printf("Writing microprogram instruction counts\n");
262
        int i;
263
        fprintf(f, "[MICROPROGRAM]\n");
264
        for (i = 0; i < microcode_size(); i++) {
265
                fprintf(f, "0x%08X %llu\n", i, p->instruction_execs[i]);
266
        }
267
}
268
 
269
void sim_write_instr_counts(profile_t* p, FILE* f)
270
{
271
        printf("Writing total instruction type counts\n");
272
        int i;
273
        fprintf(f, "[TYPECOUNT]\n");
274
        for(i = 0; i < NUM_INSTRUCTIONS; i++) {
275
                if(instruction_type != NULL)
276
                        fprintf(f, "%s %llu\n", instruction_type(i), p->num_per_type[i]);
277
        }
278
}
279
 
280
void sim_write_branch_counts(profile_t* p, FILE* f)
281
{
282
        printf("Writing branch predicts and mispredicts\n");
283
        fprintf(f, "[BRANCH-PREDICT]\n");
284
        fprintf(f, "%llu\n", p->br_predict);
285
 
286
        fprintf(f, "[BRANCH-MISPREDICT]\n");
287
        fprintf(f, "%llu\n", p->br_mispredict);
288
}
289
 
290
 
291
 
292
 
293
 
294
/*------------------*/
295
/* Cache simulation */
296
/*------------------*/
297
 
298
void cache_load(cache_t* c, unsigned int addr)
299
{
300
        /* Do cache load, register hit or miss */
301
        int position = addr % c->size;
302
        if(c->storage[position] == addr) {
303
                c->hits++;
304
        } else {
305
                c->storage[position] = addr;
306
                c->misses++;
307
        }
308
}
309
 
310
void cache_init(cache_t* c, int size)
311
{
312
        c->storage = calloc(size, sizeof(unsigned int));
313
        c->size = size;
314
        c->hits = 0;
315
        c->misses = 0;
316
}
317
 
318
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.