Commit 7f60b910 authored by Gaurav Kukreja's avatar Gaurav Kukreja

Branch Predictor

Signed-off-by: Gaurav Kukreja's avatarGaurav Kukreja <gaurav@gauravk.in>
parent 679f6800
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="cdt.managedbuild.toolchain.gnu.base.992304088">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.992304088" moduleId="org.eclipse.cdt.core.settings" name="Default">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration buildProperties="" id="cdt.managedbuild.toolchain.gnu.base.992304088" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
<folderInfo id="cdt.managedbuild.toolchain.gnu.base.992304088.348474428" name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.base.562303481" name="cdt.managedbuild.toolchain.gnu.base" superClass="cdt.managedbuild.toolchain.gnu.base">
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.1601399728" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
<builder id="cdt.managedbuild.target.gnu.builder.base.1508323901" managedBuildOn="false" name="Gnu Make Builder.Default" superClass="cdt.managedbuild.target.gnu.builder.base"/>
<tool id="cdt.managedbuild.tool.gnu.archiver.base.1136083684" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1052829016" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base"/>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.863213174" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base"/>
<tool id="cdt.managedbuild.tool.gnu.c.linker.base.2031525796" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.314488841" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base"/>
<tool id="cdt.managedbuild.tool.gnu.assembler.base.897217205" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base"/>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="branch_predictor.null.1371780544" name="branch_predictor"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
</cproject>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>branch_predictor</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>
# Makefile for cache simulator
include Makefile.macros
SRC = $(BPRED_SRC)
LIB = $(BPRED_LIB)
INSTALL = cp
all: branchPred
branchPred:
$(MAKE) -C $(SRC)
$(INSTALL) $(SRC)/lib$@.so $(LIB)
clean:
rm -rf *.o
rm -rf $(LIB)/libbranchPred.so
# Configuration for cache simulator
# Stupid Makefile Issue: Make sure no white space at the end of the variable declarations
# http://stackoverflow.com/questions/18136918/how-to-get-current-directory-of-your-makefile
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
current_dir := $(patsubst %/,%,$(dir $(mkfile_path)))
# Path to Cache Simulator
BPRED_DIR := $(current_dir)
BPRED_SRC = $(BPRED_DIR)/src
BPRED_HEADERS = $(BPRED_DIR)/headers/
BPRED_LIB = $(BPRED_DIR)/lib/
/**
* Called when a new branch is entered.
*
* name: string containing name of the basic block.
* blockObjStartAdd : Starting address of basic block from objdump
* blockObjEndAdd : End address of basic block from objdump
*
* returns whether branch was predicted or not
*/
extern unsigned int enterBlock (unsigned long blockObjStartAdd,
unsigned long blockObjEndAdd);
extern void branchPred_init();
include ../Makefile.macros
GCC = gcc
CFLAGS = -O3
HEADERS = $(BPRED_HEADERS)
# Cache Simulation Source Code
SOURCES = branchPred.c $(HEADERS)/branchPred.h
OBJECTS = branchPred.o
all: branchPred
branchPred: $(SOURCES)
$(GCC) $(CFLAGS) -c -Wall -Werror -fpic $^
$(GCC) -shared -o lib$@.so $(OBJECTS)
clean:
rm -rf *.o libbranchPred.so
\ No newline at end of file
#include <stdio.h>
#include <stdlib.h>
#define BPRED_TABLE_MAX_ENTRIES 125
enum predictionValues {
UNKNOWN = -1,
STRONGLY_TAKEN = 0,
WEAKLY_TAKEN,
WEAKLY_NOT_TAKEN,
STRONGLY_NOT_TAKEN
};
typedef enum predictionValues prediction_t;
struct bPredTableEntry
{
unsigned long branchInstAdd;
prediction_t prediction;
struct bPredTableEntry *next;
struct bPredTableEntry *prev;
};
typedef struct bPredTableEntry bPredTableEntry_t;
bPredTableEntry_t *bPredTable_head;
bPredTableEntry_t *bPredTable_tail;
unsigned int bPredTableEntries;
unsigned int prevBlockValid;
unsigned long prevBlockEndAdd;
void removeHeadEntry()
{
// bPredTable_head and the next pointer must not be NULL
// TODO: Add an assert!
bPredTableEntry_t *tmp;
tmp = bPredTable_head;
bPredTable_head = bPredTable_head->next;
bPredTable_head->prev = NULL;
free(tmp);
}
void insertEntryToTail(bPredTableEntry_t *entry)
{
if (bPredTableEntries == BPRED_TABLE_MAX_ENTRIES)
{
// Table Capacity full, must remove least recently used to make space
}
if (bPredTable_head == NULL &&
bPredTable_tail == NULL)
{
entry->next = NULL;
entry->prev = NULL;
bPredTable_head = entry;
bPredTable_tail = entry;
return;
}
else
{
bPredTable_tail->next = entry;
entry->prev = bPredTable_tail;
entry->next = NULL;
bPredTable_tail = entry;
return;
}
}
void moveEntryToTail(bPredTableEntry_t *entry)
{
if (entry->next == NULL)
return; // already at tail
else if (entry->prev == NULL) {
// Entry is head
bPredTable_head = entry->next;
bPredTable_head->prev = NULL;
bPredTable_tail->next = entry;
entry->prev = bPredTable_tail;
entry->next = NULL;
bPredTable_tail = entry;
return;
}
else
{
entry->prev->next = entry->next;
entry->next->prev = entry->prev;
bPredTable_tail->next = entry;
entry->prev = bPredTable_tail;
entry->next = NULL;
bPredTable_tail = entry;
return;
}
}
/**
* Called when a new branch is entered.
*
* name: string containing name of the basic block.
* blockObjStartAdd : Starting address of basic block from objdump
* blockObjEndAdd : End address of basic block from objdump
*
* returns whether branch was predicted or not
*/
unsigned int enterBlock (unsigned long blockObjStartAdd,
unsigned long blockObjEndAdd)
{
int isBranchTaken;
int predicted = -1;
if (!prevBlockValid)
{
// No Previous block, so branch not predicted!
// Set current block as previous
prevBlockValid = 1;
prevBlockEndAdd = blockObjEndAdd;
predicted = 0;
}
if (blockObjStartAdd == prevBlockEndAdd + 4)
{
// Branch was not taken!
isBranchTaken = 0;
}
else
{
// Branch was taken!
isBranchTaken = 1;
}
bPredTableEntry_t *entry = bPredTable_tail;
while(entry != NULL)
{
if (entry->branchInstAdd == prevBlockEndAdd)
{
// Entry Found!
if (entry->prediction == STRONGLY_NOT_TAKEN)
{
if (isBranchTaken)
{
entry->prediction = WEAKLY_NOT_TAKEN;
predicted = 0; // not predicted
break;
}
else
{
predicted = 1; // predicted
break;
}
}
if (entry->prediction == WEAKLY_NOT_TAKEN)
{
if (isBranchTaken)
{
entry->prediction = WEAKLY_TAKEN;
predicted = 0; // not predicted
break;
}
else
{
entry->prediction = STRONGLY_NOT_TAKEN;
predicted = 1; // predicted
break;
}
}
if (entry->prediction == WEAKLY_TAKEN)
{
if (isBranchTaken)
{
entry->prediction = STRONGLY_TAKEN;
predicted = 1; // predicted
break;
}
else
{
entry->prediction = WEAKLY_NOT_TAKEN;
predicted = 0; // not predicted
break;
}
}
if (entry->prediction == STRONGLY_TAKEN)
{
if (isBranchTaken)
{
predicted = 1; // predicted
break;
}
else
{
entry->prediction = WEAKLY_TAKEN;
predicted = 0; // not predicted
break;
}
}
}
entry = entry->prev;
}
if (entry != NULL)
{
// Entry was found!
moveEntryToTail(entry);
}
else
{
// Entry was not found!
entry = malloc(sizeof(bPredTableEntry_t));
entry->branchInstAdd = blockObjEndAdd;
if (isBranchTaken)
{
entry->prediction = WEAKLY_NOT_TAKEN;
predicted = 0;
}
else
{
entry->prediction = STRONGLY_NOT_TAKEN;
predicted = 1;
}
insertEntryToTail(entry);
}
prevBlockEndAdd = blockObjEndAdd;
// if (!predicted)
// {
// printf("Branch NOT Predicted\n");
// }
return predicted;
}
void branchPred_init() {
bPredTable_head = NULL;
bPredTable_tail = NULL;
bPredTableEntries = 0;
prevBlockValid = 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment