#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/******************************************************************************
Branch Prediction Simulator
(c) M. Lutfi, 2009
******************************************************************************/
#define ROW_MAJOR_ADDR(A, r, c, n) ((A) + (r)*(n) + (c))
typedef enum {
not_taken = 0,
taken
} branch_t;
typedef enum {
strongly_not_taken = 0,
weakly_not_taken,
weakly_taken,
strongly_taken
} branch_state_t;
typedef struct {
unsigned int correctPredictionCount;
branch_state_t state;
unsigned int n_iter;
} lbp_t;
enum {
BRANCH_A = 0,
BRANCH_B,
BRANCH_C,
BRANCH_D,
N_OF_BRANCHES
};
#define NBITS_OF_GBH 3 // number of bits in Global History register
lbp_t lbp_table[NBITS_OF_GBH][N_OF_BRANCHES];
unsigned char gbh=0; // global branch history register (3-bit only)
branch_t last_outcome = not_taken;
char* get_branch_state_str(branch_t b)
{
if (b == not_taken)
return "not_taken";
else
return "taken";
}
void update_gbh(void)
{
#if 0
gbh = (gbh<<1) | last_outcome;
gbh &= ((1<printf("last_outcome = %s\n", get_branch_state_str(last_outcome));
printf("gbh = %0X\n", gbh);
#endif
}
/* Local Branch Prediction FSM */
void lbp_update(lbp_t *lbp, branch_t outcome)
{
switch (lbp->state) {
case strongly_not_taken:
if (outcome == taken) {
lbp->state = weakly_not_taken;
} else {
lbp->correctPredictionCount++;
}
break;
case weakly_not_taken:
if (outcome == taken) {
lbp->state = weakly_taken;
} else {
lbp->state = strongly_not_taken;
}
break;
case weakly_taken:
if (outcome == taken) {
lbp->state = strongly_taken;
} else
lbp->state = weakly_not_taken;
break;
case strongly_taken:
if (outcome == taken) {
lbp->correctPredictionCount++;
} else {
// the outcome is NT
lbp->state = weakly_taken;
}
break;
}
lbp->n_iter++;
}
int fun(double *p, int n)
{
int r = 0;
int c = 0;
double *pA;
while (r <= n-1) {
last_outcome = not_taken;
update_gbh();
lbp_update(&lbp_table[gbh][BRANCH_A], not_taken);
while (c <= n-1) {
last_outcome = not_taken;
update_gbh();
pA = ROW_MAJOR_ADDR(p, r, c, n);
if (r < c) {
lbp_update(&lbp_table[gbh][BRANCH_C], not_taken);
*pA = 2* (*pA) + 1;
last_outcome = not_taken;
} else {
lbp_update(&lbp_table[gbh][BRANCH_C], taken);
last_outcome = taken;
}
if (r > c) {
lbp_update(&lbp_table[gbh][BRANCH_D], not_taken);
*pA = 2* (*pA) - 1;
last_outcome = not_taken;
} else {
lbp_update(&lbp_table[gbh][BRANCH_D], taken);
last_outcome = taken;
}
++c;
}
lbp_update(&lbp_table[gbh][BRANCH_B], taken);
last_outcome = taken;
update_gbh();
++r;
}
lbp_update(&lbp_table[gbh][BRANCH_A], taken);
last_outcome = taken;
update_gbh();
return 0;
}
void print_A(double *p, int n)
{
int i,j;
double *pA;
for (i=0; i<n; i++) {
for(j=0; j<n; j++) {
pA = ROW_MAJOR_ADDR(p, i, j, n);
if (!pA) return;
printf("%d: &A[%d][%d] = %0X,\t", __LINE__, i, j, pA);
printf("%d: A[%d][%d] = %lf\n", __LINE__, i, j, *pA);
}
}
}
void init_gbh(void)
{
int i,j;
lbp_t *lbpP;
gbh = 0;
for(i=0; i<(NBITS_OF_GBH<<3); i++) {
lbpP = (lbp_t*)&lbp_table[i];
for(j=0; j<N_OF_BRANCHES; j++) {
lbpP[j].correctPredictionCount = 0;
lbpP[j].state = weakly_not_taken;
lbpP[j].n_iter = 0;
}
}
}
int main(void)
{
#define N 50
double A[N][N];
int i,j;
init_gbh();
printf("sizeof(double) = %d\n", sizeof(double));
printf("%d: &A = %0X\n", __LINE__, &A[0][0]);
for(i=0; i<N; i++) {
for(j=0; j<N; j++) {
A[i][j] = ROW_MAJOR_ADDR(1, i, j, N);
}
}
fun(&A[0][0], N);
printf("gbh = %0X\n", gbh);
for(i=0; i<N_OF_BRANCHES; i++) {
printf("lbp[%d] iteration = %d\n", i, lbp_table[gbh][i].n_iter);
printf("lbp[%d] correct prediction count = %d\n",
i, lbp_table[gbh][i].correctPredictionCount);
printf("Correct Prediction Rate = %4.2lf%\n\n",
((double)(lbp_table[gbh][i].correctPredictionCount)/(double)lbp_table[gbh][i].n_iter) *100.0);
}
}
Friday, May 8, 2009
Branch Prediction Algorithm
Subscribe to:
Post Comments (Atom)
tulisan yg bagus, tp aplikasi branch prediction ini bwt apa yaa?
ReplyDeleteBranch Prediction Algorithm diimplementasikan di semua mikroprosesor (baik dari Intel, AMD, Sun, MIPS, etc.). Semuanya sudah built-in tersedia secara hardware.
ReplyDelete