blob: a59b185d0a6d4286056283076de52f10f61b5662 [file] [log] [blame]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
#include "version.h"
#include "types.h"
#include "functs.h"
#include "help.h"
#include "parse_settings.h"
#define TOP_LIST_LEN 10
#define EPOCH_LENGTH 1
int list_len=0;
int top_list_len=TOP_LIST_LEN;
int epoch_length=EPOCH_LENGTH;
int def_table_size=10007;
extern int settings[];
/***************************************
* This program is modified for use in *
* benchmarking puposes. The complete *
* program was used in computer system *
* research at Chalmers University of *
* Technology, Sweden. Chalmers has *
* nothing to do with this program. *
* *
* Plese feel free to distribute this *
* program as you like. *
* *
* Peter Rundberg, biff@ce.chalmers.se *
***************************************/
conf_list_t *list=NULL;
int first=1;
def_list_t **def_table=NULL;
hard_raw_t *hard_raw_list=NULL;
void init_def_table(int def_size)
{
int i;
def_table=(def_list_t **)malloc(def_size*sizeof(def_list_t *));
if (def_table==NULL) {
fprintf(stderr,"Out of memory...\n");
exit(1);
}
for (i=0;i<def_size;i++)
def_table[i]=NULL;
}
void error(char *name)
{
exit(1);
}
int main(int c, char *v[])
{
FILE *fp,*graphfile=NULL;
/* Benchmark stuff */
char **indata_lines;
int counter=0;
uint32 mem_ops=0;
/* End Benchmark stuff */
int varv=-1; /* We want to start counting at 0 */
int place_in_varv=0;
int place_in_epoch=0;
int varv_in_epoch;
char string[100];
uint32 address;
uint32 issue_no;
int i;
/* Settings */
int data=1,name=0,verbose=0,speed=1,forward=1,fastspeed=0,imix=1;
int load_pen=0,store_pen=0,nofile=1,kernel=3,cpulimit=0,configs=0;
int show_speedup=3,thread_pen=0,commit_pen=0,use_epoch_length_as_num_of_epochs=0;
/* End -- settings */
uint32 data_pen_tot=0;
epoch_t *epoch=NULL;
int num_epochs=0,loops=0;
trans_t *trans;
load_store_t load_store;
char *settingsfile="analyzer.conf";
fprintf(stderr,"Compile date: %s\n", COMPDATE);
fprintf(stderr,"Compiler switches: %s\n", CFLAGS);
if (c<2) {
error(v[0]);
}
if (!nofile) {
parse_settings(settingsfile);
/* Applying the setting determined by the settingsfile */
load_pen=settings[0];
store_pen=settings[1];
data=settings[2];
name=settings[3];
speed=settings[4];
fastspeed=settings[5];
forward=!settings[6];
imix=settings[7];
verbose=!settings[8];
epoch_length=settings[9];
kernel=settings[10];
cpulimit=settings[11];
configs=settings[12];
show_speedup=settings[13];
thread_pen=settings[14];
commit_pen=settings[15];
use_epoch_length_as_num_of_epochs=settings[16];
}
init_def_table(def_table_size);
fp=fopen(v[c-1],"r");
if (!fp) {
fprintf(stderr,"ERROR: \tCould not find file: %s\n\n",v[c-1]);
error(v[0]);
}
do {
fgets(string,100,fp);
} while (string[0]!='E');
num_epochs = atoi(string+5);
loops=num_epochs;
if (loops<epoch_length) {
fprintf(stderr,"ERROR: Number of loop iterations is less than epoch length: %d<%d\n",num_epochs,epoch_length);
exit(0);
}
if (use_epoch_length_as_num_of_epochs) {
epoch_length=num_epochs/epoch_length;
}
if (num_epochs%epoch_length)
num_epochs = num_epochs/epoch_length+1;
else
num_epochs = num_epochs/epoch_length;
if (num_epochs==0) {
fprintf(stderr,"File %s is empty\n",v[c-1]);
exit(0);
}
printf("Num_epochs: %d\n",num_epochs);
rewind(fp);
if (fastspeed)
speedup_test(fp);
if (imix)
mem_ops=imix_test(fp);
if (data || name || speed) {
epoch=(epoch_t *)malloc(num_epochs*sizeof(epoch_t));
if (!epoch) {
fprintf(stderr,"ALERT: \tOut of memory, aborting...\n");
exit(1);
}
for (i=0;i<num_epochs;i++) {
epoch[i].trans=NULL;
epoch[i].last=NULL;
epoch[i].first_trans=1;
}
/* Read the indata file to memory before processing begins. */
/* To eliminate effects of a slow disk subsystem. */
/* We only want to benchmark CPU & Memory performance. */
{
char *indata_line;
indata_lines=(char **)malloc((mem_ops+loops+10)*sizeof(char *));
while(!feof(fp)) {
indata_line=(char *)malloc(50*sizeof(char));
fgets(indata_line,50,fp);
indata_lines[counter++]=indata_line;
}
}
counter=0;
sscanf(indata_lines[counter++],"%s %lu",string,&issue_no);
/* fprintf(stderr,"DEBUG: \tLabel %s at cycle %lu...\n",string,issue_no); */
epoch[0].start_time=issue_no;
varv_in_epoch=-1;
place_in_varv=0;
while (1) {
if (!strcmp(string,"START:")) {
varv++;
varv_in_epoch++;
if (varv_in_epoch==epoch_length) {
place_in_varv=0;
varv_in_epoch=0;
sprintf(string,"%lx", address);
sscanf(string,"%lu",&issue_no);
issue_no+=data_pen_tot;
epoch[varv/epoch_length].start_time=issue_no;
if (varv/epoch_length)
epoch[varv/epoch_length-1].end_time=issue_no;
}
while(1) {
sscanf(indata_lines[counter++],"%s %lx %lu",string,&address,&issue_no);
issue_no+=data_pen_tot;
if (!strcmp(string,"LD:")) {
data_pen_tot+=(uint32)load_pen;
load_store=load_op;
trans=(trans_t *)malloc(sizeof(trans_t));
trans->load_store=load_op;
trans->address=address;
trans->issue_no=issue_no-epoch[varv/epoch_length].start_time;
trans->next=NULL;
if (epoch[varv/epoch_length].first_trans) {
epoch[varv/epoch_length].trans=trans;
epoch[varv/epoch_length].last=trans;
epoch[varv/epoch_length].first_trans=0;
} else {
epoch[varv/epoch_length].last->next=trans;
epoch[varv/epoch_length].last=trans;
}
} else if (!strcmp(string,"ST:")) {
data_pen_tot+=(uint32)store_pen;
load_store=store_op;
trans=(trans_t *)malloc(sizeof(trans_t));
trans->load_store=store_op;
trans->address=address;
trans->issue_no=issue_no-epoch[varv/epoch_length].start_time;
trans->next=NULL;
def_list_mod(address,varv/epoch_length,place_in_varv);
if (epoch[varv/epoch_length].first_trans) {
epoch[varv/epoch_length].trans=trans;
epoch[varv/epoch_length].last=trans;
epoch[varv/epoch_length].first_trans=0;
} else {
epoch[varv/epoch_length].last->next=trans;
epoch[varv/epoch_length].last=trans;
}
} else {
break;
}
/* Place to put processing... */
if (data || speed) {
/* Search the epochs read so far for RAW conflicts */
if (load_store==load_op) {
for (i=0;i<varv/epoch_length;i++) {
trans=epoch[i].trans;
place_in_epoch=-1;
while (trans!=NULL) {
place_in_epoch++;
if (trans->load_store==store_op && trans->address==address) {
def_list_t *def_placeholder=NULL;
def_placeholder=def_list_lookup(address);
if (def_placeholder!=NULL) {
if ((def_placeholder->epoch==i) &&
(def_placeholder->place_in_epoch==place_in_epoch)) {
conflict_list(address);
hard_raw_mod(address, i, place_in_epoch, trans->issue_no, varv/epoch_length, place_in_varv, issue_no-epoch[varv/epoch_length].start_time);
}
}
}
trans=(trans_t *)trans->next;
}
}
} else {
}
}
if (name) {
fprintf(stderr,"ALERT: \tName dependecy testing not implemented\n");
exit(1);
}
if (verbose && !(varv%10))
fprintf(stderr,"\rProcessing %3.2f %% ", 100*(float)varv/(float)loops);
place_in_varv++;
}
} else if (!strcmp(string,"END:")) {
if (verbose)
fprintf(stderr,"\rProcessing 100.00 %% \n");
break;
} else {
if (verbose)
fprintf(stderr,"\n");
fprintf(stderr,"ERROR: \tWrong format on file %s\n",v[c-1]);
exit(1);
}
}
}
if (data) {
conf_list_t *conf_iterator=list;
while (conf_iterator!=NULL) {
printf("%d RAW:s for 0x%lx\n",conf_iterator->accesser, conf_iterator->address);
conf_iterator=(conf_list_t *)conf_iterator->next;
}
}
if (speed) {
epoch[varv/epoch_length].end_time=epoch[varv/epoch_length].start_time+epoch[varv/epoch_length].last->issue_no;
if (forward)
find_hard_raws();
speedup_test(fp);
if (kernel ==1) {
specul_time_o(epoch, num_epochs,graphfile,show_speedup,thread_pen,commit_pen);
} else if (kernel == 2) {
specul_time_r(epoch, num_epochs, cpulimit,graphfile,show_speedup,thread_pen,commit_pen);
if (configs) {
for (i=1;i<=configs;) {
specul_time_r(epoch, num_epochs, i,graphfile,show_speedup,thread_pen,commit_pen);
i=i*2;
}
}
} else if (kernel == 3) {
specul_time_o(epoch, num_epochs,graphfile,show_speedup,thread_pen,commit_pen);
specul_time_r(epoch, num_epochs, cpulimit,graphfile,show_speedup,thread_pen,commit_pen);
if (configs) {
for (i=1;i<=configs;) {
specul_time_r(epoch, num_epochs, i,graphfile,show_speedup,thread_pen,commit_pen);
i=i*2;
}
}
} else {
fprintf(stderr,"ALERT: \tNo such kernel present\n");
exit(1);
}
}
return 0;
}