Commit ba1e2f36 authored by Alan Marchiori's avatar Alan Marchiori
Browse files

initial commit

parents
Loading
Loading
Loading
Loading

brtrace.out

0 → 100644
+0 −0

File added.

Preview size limit exceeded, changes collapsed.

global_pred.py

0 → 100644
+44 −0
Original line number Diff line number Diff line

class global_pht:
    def __init__(self, num_history_bits = 3):
        self.num_bits = num_history_bits
        
        self.num_index = 2**self.num_bits
        self.shift_register = self.num_index - 1         
        
        self.bin_fmt = "{{:0{}b}}".format(self.num_bits)
        self.counters = [ 'T' for i in range (self.num_index)]
        
    def predict(self, pc, target, outcome, verbose, learn = True):
                
        result = self.counters[self.shift_register]
                
        if verbose and learn:
            print ("predicting PC = 0x{:x}, branch history = ".format(pc) + \
                   self.bin_fmt.format(self.shift_register) + \
                   " outcome = {}".format(outcome))
            
            
            tag = {True: '<===',
                   False: ''}
            msg = {False: {True: "", False: ""},
                   True: {True: " (correct)",
                          False: " (MISSPREDICT)"}}
            for i in range (self.num_index):
                                
                print ("PHT[" + self.bin_fmt.format(i) + "] = {} {}{}".format(self.counters[i],
                                                                            tag[i == self.shift_register],
                                                                            msg[i == self.shift_register][result == outcome]))
                
            
        

        if learn:
            self.counters[self.shift_register] = outcome
        
        self.shift_register = ((self.shift_register << 1) & (self.num_index - 1))
        if outcome == 'T':
            self.shift_register |= 1
        
        return result
 No newline at end of file

hybrid_correlating.py

0 → 100644
+18 −0
Original line number Diff line number Diff line
from twolevel import correlation_register
from local import saturating_counter


class hybrid_correlating_predictor():
    def __init__(self, global_history_bits = 2, local_pc_bits = 3):        
        self.global_indexes = 2**global_history_bits        
        self.local_indexes = 2**local_pc_bits
        self.bin_fmt = "{{:0{}b}}".format(global_history_bits)
        
    def predict(self, pc, target, outcome, verbose):        
        """TODO: complete this"""
        
            
        return "T"
    
    
 No newline at end of file

local.py

0 → 100644
+48 −0
Original line number Diff line number Diff line
import math
class saturating_counter(): 
    pred = ['N', 'N', 'T', 'T']   
    def __init__(self):
        self.value = 3
    def increment(self):        
        if self.value  < 3:
            self.value += 1 
    def decrement(self):
        if self.value > 0:
            self.value -= 1
    def predict(self):
        return saturating_counter.pred[self.value]
    def __str__(self):
        return "{:02b} ({})".format(self.value, saturating_counter.pred[self.value])
    
class local_bht:
    def __init__(self, num_index_bits = 3):
        self.num_index = 2**num_index_bits        
        self.counters = [saturating_counter() for i in range(self.num_index)]
        
        # compute the correct number of significant digits
        self.bin_fmt ="{{:{}d}}".format(math.ceil(math.log10(self.num_index))) 
        
    def predict(self, pc, target, outcome, verbose):        
        i = (pc//4) % self.num_index
        result = self.counters[i].predict()

        if verbose:
            print ("predict PC = {:x}, index = {:d}, outcome = {}".format(pc, i, outcome))
            tag = {True: '<===',
                   False: ''}
            msg = {False: {True: "", False: ""},
                   True: {True: " (correct)",
                          False: " (MISSPREDICT)"}}
            
            for x in range (self.num_index):                                
                print ("BHT[" + self.bin_fmt.format(x) + "] = {} {}{}".format(self.counters[x],
                                                                            tag[i == x],
                                                                            msg[i == x][result == outcome]))

        if outcome == 'T':
            self.counters[i].increment()
        else:
            self.counters[i].decrement()
                     
        return result
 No newline at end of file

predict.py

0 → 100644
+136 −0
Original line number Diff line number Diff line
from static import static_predictor
from local import local_bht
from global_pred  import global_pht # global is a reserved word, cannot use as module name
from twolevel import twolevel_predictor
from hybrid_correlating import hybrid_correlating_predictor
from tournament import tournament_predictor

def predict(lines, verbose = False, predictor = static_predictor()):
    """Input is a generator which yields triples: (PC, branch target, [T]aken / [N]ot taken
    """
    
    stats = {True:0, 
             False:0}
    msg = {True: '',
           False: '*MISSPREDICT*'}
    for pc, target, outcome in lines:
        
        #if verbose:
        #    print()
        #    print ("-"*30)
        prd = predictor.predict(pc, target, outcome, verbose)
        
        if verbose:
            print ("0x{:x} --> 0x{:x}: pred = {} actual = {} {}".format(pc,
                                                                        target,
                                                                        prd,
                                                                        outcome,
                                                                        msg[prd == outcome]))        
        #if verbose:
        #    print ("+"*30)
        stats[prd == outcome] +=  + 1
        
    print ("Correct: {}, misspredict: {}, Accuracy: {:4.2f}%".format(stats[True],
                                                                     stats[False],
                                                                     100*stats[True]/(sum(stats.values()))))
    
    
if __name__ == "__main__":
        
    branches =  """0x31c1e011c8 0x31c1e011b0 T
 0x31c1e011c2 0x31c1e011f0 N
 0x31c1e011c8 0x31c1e011b0 T
 0x31c1e011c2 0x31c1e011f0 N
 0x31c1e011c8 0x31c1e011b0 T
 0x31c1e011c2 0x31c1e011f0 N
 0x31c1e011c8 0x31c1e011b0 T
 0x31c1e011c2 0x31c1e011f0 N
 0x31c1e011c8 0x31c1e011b0 N
 0x31c1e011d4 0x31c1e014d0 N
 0x31c1e011ee 0x31c1e011c4 T
 0x31c1e011c8 0x31c1e011b0 N
 0x31c1e011d4 0x31c1e014d0 N
 0x31c1e011ee 0x31c1e011c4 T
 0x31c1e011c8 0x31c1e011b0 T
 0x31c1e011c2 0x31c1e011f0 N
 0x31c1e011c8 0x31c1e011b0 N
 0x31c1e011d4 0x31c1e014d0 N
 0x31c1e011ee 0x31c1e011c4 T
 0x31c1e011c8 0x31c1e011b0 N
 0x31c1e011d4 0x31c1e014d0 N
 0x31c1e011ee 0x31c1e011c4 T
 0x31c1e011c8 0x31c1e011b0 N"""
    
    def parts_to_ints(parts):
        return ( int(parts[0],16), int(parts[1],16), parts[2] )     
    
    # use this line if you want to read from a file.
    #lines = open('brtrace.out').readlines()
    lines = branches.split('\n')    
    
    verb = True
    
    # which predictor or predictors you want to run...
    predictors = 'static'    
    
    if 'static' in predictors:
        for predictor, string in ( (static_predictor(), 'Static'), ):
            s = (x.strip().split(' ') for x in lines)
            s = (parts_to_ints(x) for x in s)         
            print (string, ': ')
            predict (s, verb, predictor)
      
        print ("="*60)        
    
    if 'local' in predictors:
        #for predictor, string in (
                                  #(local_bht(i), '2-bit local BHT n={:2d}'.format(i)) for i in range (1, 4)  ):
                                  
        for predictor, string in ((local_bht(3), '2-bit local BHT with {} entries'.format(2**3)),):
            s = (x.strip().split(' ') for x in lines)
            s = (parts_to_ints(x) for x in s)         
            print (string, ': ')            
            predict (s, verb, predictor)
    
        print ("="*60)
        
    if 'global' in predictors:
        #for predictor, string in (
         #                         (global_pht(i), 'Global PHT n={:2d}'.format(i)) for i in range (1, 4)  ):
        for predictor, string in ( (global_pht(3), 'Global PHT with {} entries'.format(2**3)), ):
            s = (x.strip().split(' ') for x in lines)
            s = (parts_to_ints(x) for x in s)         
            print (string, ': ')            
            predict (s, verb, predictor)          
            
        print ("="*60)
        
    if 'twolevel' in predictors:
        for predictor, string in ( (twolevel_predictor(3,3), 'Two-level with {} entries and {} counters'.format(8,8)), ):
            s = (x.strip().split(' ') for x in lines)
            s = (parts_to_ints(x) for x in s)         
            print (string, ': ')            
            predict (s, verb, predictor)          
            
        print ("="*60)
   
    if 'hybrid_correlating' in predictors:
       for predictor, string in ( (hybrid_correlating_predictor(2,3), 
                                   'Hybrid correlating with global {} bit shift register and {} BHT counters'.format(2,2**3)), ):
            s = (x.strip().split(' ') for x in lines)
            s = (parts_to_ints(x) for x in s)         
            print (string, ': ')            
            predict (s, verb, predictor)          
       print ("="*60)
       
    if 'tournament' in predictors:
       for predictor, string in ( (tournament_predictor(3, 3, 3), 
                                   'tournament predictor {} entry bht and {} bit shift register'.format(8,8)), ):
            s = (x.strip().split(' ') for x in lines)
            s = (parts_to_ints(x) for x in s)         
            print (string, ': ')            
            predict (s, verb, predictor)          
       print ("="*60)        
        
        
 No newline at end of file