diff --git a/src/bct.c b/src/bct.c index 4c2a59a..043e1ba 100644 --- a/src/bct.c +++ b/src/bct.c @@ -23,9 +23,9 @@ void BCT_Initial(BCT* BranchChooserTable, uint32_t index_width) BranchChooserTable->chooser[i] = weakly_bimodal; } -Predictor BCT_Predict(BCT* BranchChooserTable, uint32_t addr) +Predictor BCT_Predict(BCT* BranchChooserTable, uint32_t addr, uint8_t two_byte_inst) { - uint32_t index = Get_Index(addr, BranchChooserTable->attributes.index_width); + uint32_t index = Get_Index(addr, BranchChooserTable->attributes.index_width, two_byte_inst); switch (BranchChooserTable->chooser[index]) { case strongly_gshare: @@ -36,13 +36,13 @@ Predictor BCT_Predict(BCT* BranchChooserTable, uint32_t addr) } } -void BCT_Update(BCT* BranchChooserTable, uint32_t addr, Result result) +void BCT_Update(BCT* BranchChooserTable, uint32_t addr, uint8_t two_byte_inst, Result result) { if (result.actual_taken == result.predict_taken[BIMODAL] && result.actual_taken == result.predict_taken[GSHARE]) return; if (result.actual_taken != result.predict_taken[BIMODAL] && result.actual_taken != result.predict_taken[GSHARE]) return; - uint32_t index = Get_Index(addr, BranchChooserTable->attributes.index_width); + uint32_t index = Get_Index(addr, BranchChooserTable->attributes.index_width, two_byte_inst); if (result.actual_taken == result.predict_taken[GSHARE]) { switch (BranchChooserTable->chooser[index]) @@ -74,4 +74,4 @@ void BCT_fprintf(BCT* BranchChooserTable, FILE *fp) uint32_t i; for (i = 0; i < BranchChooserTable->attributes.chooser_num; i++) fprintf(fp, "Choice table[%u]: %u\n", i, BranchChooserTable->chooser[i]); -} \ No newline at end of file +} diff --git a/src/bct.h b/src/bct.h index 7d3acf0..e14e692 100644 --- a/src/bct.h +++ b/src/bct.h @@ -43,22 +43,24 @@ void BCT_Initial(BCT* BranchChooserTable, uint32_t index_width); * Search the BranchChooserTable for PC "addr" and make prediction * input : * addr : PC + * two_byte_instr: Are instructions a mix of 4 and 2 byte length. Modifies index function. * return : * the prediction on which predictor is chosen */ -Predictor BCT_Predict(BCT* BranchChooserTable, uint32_t addr); +Predictor BCT_Predict(BCT* BranchChooserTable, uint32_t addr, uint8_t two_byte_inst); /* * Update the BranchChooserTable * input : * addr : PC + * two_byte_instr: Are instructions a mix of 4 and 2 byte length. Modifies index function. * result : struct "Result", the prediction and actual result */ -void BCT_Update(BCT* BranchChooserTable, uint32_t addr, Result result); +void BCT_Update(BCT* BranchChooserTable, uint32_t addr, uint8_t two_byte_inst, Result result); /* * Print the content of BranchChooserTable to file *fp */ void BCT_fprintf(BCT* BranchChooserTable, FILE *fp); -#endif \ No newline at end of file +#endif diff --git a/src/bht.c b/src/bht.c index f27cdbd..9424073 100644 --- a/src/bht.c +++ b/src/bht.c @@ -22,16 +22,16 @@ void BHT_Initial(BHT *BranchHistoryTable, uint32_t index_width, uint32_t history memset(BranchHistoryTable->history, 0, sizeof(uint64_t) * BranchHistoryTable->attributes.history_num); } -uint64_t BHT_Search(BHT *BranchHistoryTable, uint32_t addr) +uint64_t BHT_Search(BHT *BranchHistoryTable, uint32_t addr, uint8_t two_byte_inst) { - uint32_t index = Get_Index(addr, BranchHistoryTable->attributes.index_width); + uint32_t index = Get_Index(addr, BranchHistoryTable->attributes.index_width, two_byte_inst); return BranchHistoryTable->history[index]; } -void BHT_Update(BHT *BranchHistoryTable, uint32_t addr, Result result) +void BHT_Update(BHT *BranchHistoryTable, uint32_t addr, uint8_t two_byte_inst, Result result) { - uint32_t index = Get_Index(addr, BranchHistoryTable->attributes.index_width); + uint32_t index = Get_Index(addr, BranchHistoryTable->attributes.index_width, two_byte_inst); uint64_t old_history = BranchHistoryTable->history[index]; old_history = old_history >> 1; if (result.actual_taken == TAKEN) diff --git a/src/bht.h b/src/bht.h index a68a8a1..206f8ce 100644 --- a/src/bht.h +++ b/src/bht.h @@ -34,22 +34,23 @@ void BHT_Initial(BHT *BranchHistoryTable, uint32_t index_width, uint32_t history * Search the BranchPredictionTable for PC "addr" and make prediction * input : * addr : PC - * return : + * two_byte_instr: Are instructions a mix of 4 and 2 byte length. Modifies index function. * return : * the history pattern of correspounding entry (at most 64 bits, hence uint64_t) */ -uint64_t BHT_Search(BHT *BranchHistoryTable, uint32_t addr); +uint64_t BHT_Search(BHT *BranchHistoryTable, uint32_t addr, uint8_t two_byte_inst); /* * Update the BranchPredictionTable * input : * addr : PC + * two_byte_instr: Are instructions a mix of 4 and 2 byte length. Modifies index function. * result : struct "Result", the prediction and actual result */ -void BHT_Update(BHT *BranchHistoryTable, uint32_t addr, Result result); +void BHT_Update(BHT *BranchHistoryTable, uint32_t addr, uint8_t two_byte_inst, Result result); /* * Print the content of BranchHistoryTable to file *fp */ void BHT_fprintf(BHT *BranchHistoryTable, FILE *fp); -#endif \ No newline at end of file +#endif diff --git a/src/bp.c b/src/bp.c index 41e0e7f..164b4ce 100644 --- a/src/bp.c +++ b/src/bp.c @@ -89,17 +89,17 @@ void Predictor_Init(Predictor type, uint32_t* width) } } -Taken_Result Bimodal_Predict(BP_Bimodal *predictor, uint32_t addr) +Taken_Result Bimodal_Predict(BP_Bimodal *predictor, uint32_t addr, uint8_t two_byte_inst) { - uint32_t index = Get_Index(addr, ((BPT *)predictor)->attributes.index_width); + uint32_t index = Get_Index(addr, ((BPT *)predictor)->attributes.index_width, two_byte_inst); return BPT_Predict((BPT *)predictor, index); } -Taken_Result Gshare_Predict(BP_Gshare *predictor, uint32_t addr) +Taken_Result Gshare_Predict(BP_Gshare *predictor, uint32_t addr, uint8_t two_byte_inst) { uint32_t h = predictor->global_history_register->attributes.history_width; uint32_t i = predictor->branch_prediction_table->attributes.index_width; - uint32_t index = Get_Index(addr, i); + uint32_t index = Get_Index(addr, i, two_byte_inst); uint32_t history = predictor->global_history_register->history; uint32_t mask = (1 <<((i-h)))-1; uint32_t index_tail = index & mask; @@ -108,7 +108,7 @@ Taken_Result Gshare_Predict(BP_Gshare *predictor, uint32_t addr) return BPT_Predict(predictor->branch_prediction_table, index); } -Result Predictor_Predict(uint32_t addr) +Result Predictor_Predict(uint32_t addr, uint8_t two_byte_inst) { Result result; result.predict_predictor = branch_predictor->predictor_type; @@ -116,20 +116,20 @@ Result Predictor_Predict(uint32_t addr) { case bimodal: { - result.predict_taken[BIMODAL] = Bimodal_Predict((BP_Bimodal *)branch_predictor->predictor, addr); + result.predict_taken[BIMODAL] = Bimodal_Predict((BP_Bimodal *)branch_predictor->predictor, addr, two_byte_inst); return result; } case gshare: { - result.predict_taken[GSHARE] = Gshare_Predict((BP_Gshare *)branch_predictor->predictor, addr); + result.predict_taken[GSHARE] = Gshare_Predict((BP_Gshare *)branch_predictor->predictor, addr, two_byte_inst); return result; } case hybrid: { BP_Hybrid *predictor = branch_predictor->predictor; - result.predict_taken[BIMODAL] = Bimodal_Predict(predictor->bp_bimodal, addr); - result.predict_taken[GSHARE] = Gshare_Predict(predictor->bp_gshare, addr); - result.predict_predictor = BCT_Predict(predictor->branch_chooser_table, addr); + result.predict_taken[BIMODAL] = Bimodal_Predict(predictor->bp_bimodal, addr, two_byte_inst); + result.predict_taken[GSHARE] = Gshare_Predict(predictor->bp_gshare, addr, two_byte_inst); + result.predict_predictor = BCT_Predict(predictor->branch_chooser_table, addr, two_byte_inst); if (result.predict_predictor == bimodal) result.predict_taken[HYBRID] = result.predict_taken[BIMODAL]; else @@ -139,7 +139,7 @@ Result Predictor_Predict(uint32_t addr) case yeh_patt: { BP_Yeh_Patt *predictor = branch_predictor->predictor; - uint64_t history = BHT_Search(predictor->branch_histroy_table, addr); + uint64_t history = BHT_Search(predictor->branch_histroy_table, addr, two_byte_inst); result.predict_taken[YEH_PATT] = BPT_Predict(predictor->branch_predition_table, history); return result; } @@ -148,17 +148,17 @@ Result Predictor_Predict(uint32_t addr) } } -void Bimodal_Update(BP_Bimodal *predictor, uint32_t addr, Result result) +void Bimodal_Update(BP_Bimodal *predictor, uint32_t addr, uint8_t two_byte_inst, Result result) { - uint32_t index = Get_Index(addr, ((BPT *)predictor)->attributes.index_width); + uint32_t index = Get_Index(addr, ((BPT *)predictor)->attributes.index_width, two_byte_inst); BPT_Update(predictor, index, result); } -void Gshare_Update(BP_Gshare *predictor, uint32_t addr, Result result) +void Gshare_Update(BP_Gshare *predictor, uint32_t addr, uint8_t two_byte_inst, Result result) { uint32_t h = predictor->global_history_register->attributes.history_width; uint32_t i = predictor->branch_prediction_table->attributes.index_width; - uint32_t index = Get_Index(addr, i); + uint32_t index = Get_Index(addr, i, two_byte_inst); uint32_t history = predictor->global_history_register->history; uint32_t mask = (1 <<((i-h)))-1; uint32_t index_tail = index & mask; @@ -167,19 +167,19 @@ void Gshare_Update(BP_Gshare *predictor, uint32_t addr, Result result) BPT_Update(predictor->branch_prediction_table, index, result); } -void Predictor_Update(uint32_t addr, Result result) +void Predictor_Update(uint32_t addr, uint8_t two_byte_inst, Result result) { switch (branch_predictor->predictor_type) { case bimodal: { - Bimodal_Update((BP_Bimodal *)branch_predictor->predictor, addr, result); + Bimodal_Update((BP_Bimodal *)branch_predictor->predictor, addr, two_byte_inst, result); return; } case gshare: { BP_Gshare *predictor = branch_predictor->predictor; - Gshare_Update(predictor, addr, result); + Gshare_Update(predictor, addr, two_byte_inst, result); GHR_Update(predictor->global_history_register, result); return; } @@ -187,19 +187,19 @@ void Predictor_Update(uint32_t addr, Result result) { BP_Hybrid *predictor = branch_predictor->predictor; if (result.predict_predictor == bimodal) - Bimodal_Update(predictor->bp_bimodal, addr, result); + Bimodal_Update(predictor->bp_bimodal, addr, two_byte_inst, result); else - Gshare_Update(predictor->bp_gshare, addr, result); + Gshare_Update(predictor->bp_gshare, addr, two_byte_inst, result); GHR_Update(predictor->bp_gshare->global_history_register, result); - BCT_Update(predictor->branch_chooser_table, addr, result); + BCT_Update(predictor->branch_chooser_table, addr, two_byte_inst, result); return; } case yeh_patt: { BP_Yeh_Patt *predictor = branch_predictor->predictor; - uint64_t history = BHT_Search(predictor->branch_histroy_table, addr); + uint64_t history = BHT_Search(predictor->branch_histroy_table, addr, two_byte_inst); BPT_Update(predictor->branch_predition_table, history, result); - BHT_Update(predictor->branch_histroy_table, addr, result); + BHT_Update(predictor->branch_histroy_table, addr, two_byte_inst, result); return; } } diff --git a/src/bp.h b/src/bp.h index 4d0e632..dcaa1ea 100644 --- a/src/bp.h +++ b/src/bp.h @@ -58,36 +58,36 @@ void Predictor_Init(Predictor name, uint32_t* width); /* * Prediction on taken_or_not of bimodal predictor */ -Taken_Result Bimodal_Predict(BP_Bimodal *predictor, uint32_t addr); +Taken_Result Bimodal_Predict(BP_Bimodal *predictor, uint32_t addr, uint8_t two_byte_inst); /* * Prediction on taken_or_not of gshare predictor */ -Taken_Result Gshare_Predict(BP_Gshare *predictor, uint32_t addr); +Taken_Result Gshare_Predict(BP_Gshare *predictor, uint32_t addr, uint8_t two_byte_inst); /* * Prediction of bimodal predictor */ -Result Predictor_Predict(uint32_t addr); +Result Predictor_Predict(uint32_t addr, uint8_t two_byte_inst); /* * Update bimodal prediction table */ -void Bimodal_Update(BP_Bimodal *predictor, uint32_t addr, Result result); +void Bimodal_Update(BP_Bimodal *predictor, uint32_t addr, uint8_t two_byte_inst, Result result); /* * Update gshare prediction table */ -void Gshare_Update(BP_Gshare *predictor, uint32_t addr, Result result); +void Gshare_Update(BP_Gshare *predictor, uint32_t addr, uint8_t two_byte_inst, Result result); /* * Update predictior */ -void Predictor_Update(uint32_t addr, Result result); +void Predictor_Update(uint32_t addr, uint8_t two_byte_inst, Result result); /* * Print the content of branch_predictor to file *fp */ void BP_fprintf(FILE *fp); -#endif \ No newline at end of file +#endif diff --git a/src/main.c b/src/main.c index 002f532..9b2958f 100644 --- a/src/main.c +++ b/src/main.c @@ -17,6 +17,7 @@ char *trace_file; int main(int argc, char *argv[]) { + uint8_t two_byte_inst; #ifdef DBG debug_fp = fopen("debug.txt", "w"); if (debug_fp == NULL) @@ -26,7 +27,7 @@ int main(int argc, char *argv[]) Predictor type; uint32_t width[9]; - parse_arguments(argc, argv, &type, width); + parse_arguments(argc, argv, &type, width, &two_byte_inst); branch_target_buffer = NULL; branch_predictor = NULL; @@ -59,31 +60,42 @@ int main(int argc, char *argv[]) /* read the trace */ uint8_t take_or_not, line; uint32_t addr; - int rr = fscanf(trace_file_fp, "%x %c%c", &addr, &take_or_not, &line); + char buf[256]; + char * rr = fgets(buf, 256, trace_file_fp); trace_count++; - if (rr == EOF) + if (rr == NULL) break; - /* make branch prediction */ - Result result = Predictor_Predict(addr); - if (branch_target_buffer == NULL) - result.predict_branch = branch; - else - result.predict_branch = BTB_Predict(addr); - - result.actual_branch = branch; - if (take_or_not == 't') - result.actual_taken = taken; + // check for the begining of the branch trace. Remove results from stats + // as the earlier section as bp training. + if(!strncmp(buf, "BEGIN", 5)) { + printf("Reset stats\n"); + Stat_Init(); + } else - result.actual_taken = not_taken; - - /* update the predictor and statistic data */ - Update_Stat(result); - if (result.predict_branch == branch) - Predictor_Update(addr, result); - if (branch_target_buffer != NULL) - BTB_Update(addr, result, trace_count); - + { + sscanf(buf, "%x %c%c", &addr, &take_or_not, &line); + + /* make branch prediction */ + Result result = Predictor_Predict(addr, two_byte_inst); + if (branch_target_buffer == NULL) + result.predict_branch = branch; + else + result.predict_branch = BTB_Predict(addr); + + result.actual_branch = branch; + if (take_or_not == 't') + result.actual_taken = taken; + else + result.actual_taken = not_taken; + + /* update the predictor and statistic data */ + Update_Stat(result); + if (result.predict_branch == branch) + Predictor_Update(addr, two_byte_inst, result); + if (branch_target_buffer != NULL) + BTB_Update(addr, result, trace_count); + } } FILE *fp = stdout; diff --git a/src/utils.c b/src/utils.c index 8581ee6..26c726e 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,38 +1,64 @@ #include #include #include +#include +#include + #include "utils.h" #include "btb.h" #include "bp.h" -void parse_arguments(int argc, char * argv[], Predictor *type, uint32_t* width) +void parse_arguments(int argc, char * argv[], Predictor *type, uint32_t* width, uint8_t* two_byte_inst) { - if (argc < 6 || argc > 9 || argc == 8) + *two_byte_inst = 0; + int index; + int c; + + opterr = 0; + + while ((c = getopt (argc, argv, "c")) != -1) + switch (c) + { + case 'c': + *two_byte_inst = 1; + break; + case '?': + if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); + else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); + return; + default: + abort (); + } + + index = optind - 1; + int new_argc = argc - index; + + if (new_argc < 6 || new_argc > 9 || new_argc == 8) _output_error_exit("wrong number of input parameters") - if (strcmp(argv[1], "bimodal") == 0) + if (strcmp(argv[1+index], "bimodal") == 0) { *type = bimodal; - if (argc != 6) + if (new_argc != 6) _output_error_exit("wrong number of input parameters") } - else if (strcmp(argv[1], "gshare") == 0) + else if (strcmp(argv[1+index], "gshare") == 0) { *type = gshare; - if (argc != 7) + if (new_argc != 7) _output_error_exit("wrong number of input parameters") } - else if (strcmp(argv[1], "hybrid") == 0) + else if (strcmp(argv[1+index], "hybrid") == 0) { *type = hybrid; - if (argc != 9) + if (new_argc != 9) _output_error_exit("wrong number of input parameters") } - else if (strcmp(argv[1], "yehpatt") == 0) + else if (strcmp(argv[1+index], "yehpatt") == 0) { *type = yeh_patt; - if (argc != 7) + if (new_argc != 7) _output_error_exit("wrong number of input parameters") } else @@ -42,39 +68,39 @@ void parse_arguments(int argc, char * argv[], Predictor *type, uint32_t* width) { case bimodal: { - width[BIMODAL] = atoi(argv[2]); - width[BTBuffer] = atoi(argv[3]); - width[ASSOC] = atoi(argv[4]); - trace_file = argv[5]; + width[BIMODAL] = atoi(argv[2+index]); + width[BTBuffer] = atoi(argv[3+index]); + width[ASSOC] = atoi(argv[4+index]); + trace_file = argv[5+index]; break; } case gshare: { - width[GSHARE] = atoi(argv[2]); - width[GHRegister] = atoi(argv[3]); - width[BTBuffer] = atoi(argv[4]); - width[ASSOC] = atoi(argv[5]); - trace_file = argv[6]; + width[GSHARE] = atoi(argv[2+index]); + width[GHRegister] = atoi(argv[3+index]); + width[BTBuffer] = atoi(argv[4+index]); + width[ASSOC] = atoi(argv[5+index]); + trace_file = argv[6+index]; break; } case hybrid: { - width[BCTable] = atoi(argv[2]); - width[GSHARE] = atoi(argv[3]); - width[GHRegister] = atoi(argv[4]); - width[BIMODAL] = atoi(argv[5]); - width[BTBuffer] = atoi(argv[6]); - width[ASSOC] = atoi(argv[7]); - trace_file = argv[8]; + width[BCTable] = atoi(argv[2+index]); + width[GSHARE] = atoi(argv[3+index]); + width[GHRegister] = atoi(argv[4+index]); + width[BIMODAL] = atoi(argv[5+index]); + width[BTBuffer] = atoi(argv[6+index]); + width[ASSOC] = atoi(argv[7+index]); + trace_file = argv[8+index]; break; } case yeh_patt: { - width[BHTable] = atoi(argv[2]); - width[YEH_PATT] = atoi(argv[3]); - width[BTBuffer] = atoi(argv[4]); - width[ASSOC] = atoi(argv[5]); - trace_file = argv[6]; + width[BHTable] = atoi(argv[2+index]); + width[YEH_PATT] = atoi(argv[3+index]); + width[BTBuffer] = atoi(argv[4+index]); + width[ASSOC] = atoi(argv[5+index]); + trace_file = argv[6+index]; break; } } @@ -88,8 +114,14 @@ void Stat_Init() memset(stat.num_misprediction, 0, sizeof(uint64_t) * 6); } -uint32_t Get_Index(uint32_t addr, uint32_t index_width) +uint32_t Get_Index(uint32_t addr, uint32_t index_width, uint8_t two_byte_inst) { + if(two_byte_inst) + { + uint32_t lsb; + lsb = (addr & 2) << index_width; + addr = addr ^ lsb; + } return (addr << (30 - index_width)) >> (32 - index_width); } diff --git a/src/utils.h b/src/utils.h index ed661cc..377ba02 100644 --- a/src/utils.h +++ b/src/utils.h @@ -91,7 +91,7 @@ extern char *trace_file; * width[BTBuffer] : all i_BTB * width[ASSOC] : all assoc */ -void parse_arguments(int argc, char * argv[], Predictor *type, uint32_t* width); +void parse_arguments(int argc, char * argv[], Predictor *type, uint32_t* width, uint8_t *two_byte_inst); /* * Initial the stat (global statistic data) @@ -101,7 +101,7 @@ void Stat_Init(); /* * get index from "addr" */ -uint32_t Get_Index(uint32_t addr, uint32_t index_width); +uint32_t Get_Index(uint32_t addr, uint32_t index_width, uint8_t two_byte_inst); /* * Update the stat according to result