私が現在取り組んでいる問題は、分岐命令アドレスと、2 ビットの飽和カウンターの取得/未取得命令を受け取る gshare シミュレーターを作成することです。つまり、私の入力は次のようになります。
0ffd7a78 1
私が作成した 2 ビット飽和カウンター プログラムは、予測ミスの数と予測ミス率を正しく計算します。2 ビット飽和カウンターの背後にあるロジックを理解しています。ただし、gshare シミュレーターの概念に頭を悩ませています。私の場合、BHSR (Branch History Shift Register) を使用します。このシミュレーターは、最下位ビットからのビット数で XOR された可変ビット インデックスで構成されます。命令アドレスの。私の理解では、BHSR には最後の n 回の発生が含まれており、パターン履歴テーブルにインデックスを付けるために使用されます。パターン履歴テーブルの各エントリには、予測を行うために使用される独自の 2 ビット飽和カウンターが含まれています。私はこれに何時間も取り組んだり考えたりしてきましたが、おそらく考えすぎているだけです。2 ビット飽和カウンターを実装して複数の 2 ビット飽和カウンターのテーブルを作成し、パターン履歴テーブルに入力するにはどうすればよいですか? ここで質問するのは初めてなので、正しい形式に従っていることを願っています。2 ビット飽和カウンター プログラムのコードは次のとおりです。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define RECORDS 4000000
int main(int argc, char *argv[]){
int bitIndex = atoi(argv[1]); //The argument entered by the user, defines bit index
int numEntries; //Number of entries as determined by bit index
numEntries = pow(2, bitIndex);
int bht[numEntries]; //Integer array that holds the Branch History Table
int count; //Used to clear out the Branch History Table
//Loop through the entire Branch History Table and make sure all cells are set to 0.
for(count = 0; count < numEntries; count++){
bht[count] = 0;
}
int i; //Set up our counter
int mispredict = 0; //Tells the number of mispredicts
int predict = 0; //Tells the number of correct predictions
//Branch Prediction Record
char hexAddress[8]; //Address in branch prediction record stored as a string
int direction; //The 0 or 1 will tell us whether to go up or down in a state change
for(i = 0; i < RECORDS; i++){
scanf("%s %d", hexAddress, &direction);
//printf("The address is %s\nThe direction is %d\n", hexAddress, direction);
//BEGIN NUMBER CONVERSION
//LOOKING FOR LEAST SIGNIFICANT BITS (bitIndex)
//CONVERT HEX ADDRESS TO BINARY
char originalHexAddress[8];
strcpy(originalHexAddress, hexAddress); //Preserve the original address
int j; //Counter for this internal loop
char binaryString[32] = {""}; //Sets up a "string" for the binary conversion
//Loop through the hex address and turn each component into its binary counterpart
for(j = 0; j < 8; j++){
if(hexAddress[j] == '0'){
if(binaryString[0] == '\0'){
strcpy(binaryString, "0000");
}
else{
strcat(binaryString, "0000");
}
}
if(hexAddress[j] == '1'){
if(binaryString[0] == '\0'){
strcpy(binaryString, "0001");
}
else{
strcat(binaryString, "0001");
}
}
if(hexAddress[j] == '2'){
if(binaryString[0] == '\0'){
strcpy(binaryString, "0010");
}
else{
strcat(binaryString, "0010");
}
}
if(hexAddress[j] == '3'){
if(binaryString[0] == '\0'){
strcpy(binaryString, "0011");
}
else{
strcat(binaryString, "0011");
}
}
if(hexAddress[j] == '4'){
if(binaryString[0] == '\0'){
strcpy(binaryString, "0100");
}
else{
strcat(binaryString, "0100");
}
}
if(hexAddress[j] == '5'){
if(binaryString[0] == '\0'){
strcpy(binaryString, "0101");
}
else{
strcat(binaryString, "0101");
}
}
if(hexAddress[j] == '6'){
if(binaryString[0] == '\0'){
strcpy(binaryString, "0110");
}
else{
strcat(binaryString, "0110");
}
}
if(hexAddress[j] == '7'){
if(binaryString[0] == '\0'){
strcpy(binaryString, "0111");
}
else{
strcat(binaryString, "0111");
}
}
if(hexAddress[j] == '8'){
if(binaryString[0] == '\0'){
strcpy(binaryString, "1000");
}
else{
strcat(binaryString, "1000");
}
}
if(hexAddress[j] == '9'){
if(binaryString[0] == '\0'){
strcpy(binaryString, "1001");
}
else{
strcat(binaryString, "1001");
}
}
if(hexAddress[j] == 'A'){
if(binaryString[0] == '\0'){
strcpy(binaryString, "1010");
}
else{
strcat(binaryString, "1010");
}
}
if(hexAddress[j] == 'B'){
if(binaryString[0] == '\0'){
strcpy(binaryString, "1011");
}
else{
strcat(binaryString, "1011");
}
}
if(hexAddress[j] == 'C'){
if(binaryString[0] == '\0'){
strcpy(binaryString, "1100");
}
else{
strcat(binaryString, "1100");
}
}
if(hexAddress[j] == 'D'){
if(binaryString[0] == '\0'){
strcpy(binaryString, "1101");
}
else{
strcat(binaryString, "1101");
}
}
if(hexAddress[j] == 'E'){
if(binaryString[0] == '\0'){
strcpy(binaryString, "1110");
}
else{
strcat(binaryString, "1110");
}
}
if(hexAddress[j] == 'F'){
if(binaryString[0] == '\0'){
strcpy(binaryString, "1111");
}
else{
strcat(binaryString, "1111");
}
}
if(hexAddress[j] == 'a'){
if(binaryString[0] == '\0'){
strcpy(binaryString, "1010");
}
else{
strcat(binaryString, "1010");
}
}
if(hexAddress[j] == 'b'){
if(binaryString[0] == '\0'){
strcpy(binaryString, "1011");
}
else{
strcat(binaryString, "1011");
}
}
if(hexAddress[j] == 'c'){
if(binaryString[0] == '\0'){
strcpy(binaryString, "1100");
}
else{
strcat(binaryString, "1100");
}
}
if(hexAddress[j] == 'd'){
if(binaryString[0] == '\0'){
strcpy(binaryString, "1101");
}
else{
strcat(binaryString, "1101");
}
}
if(hexAddress[j] == 'e'){
if(binaryString[0] == '\0'){
strcpy(binaryString, "1110");
}
else{
strcat(binaryString, "1110");
}
}
if(hexAddress[j] == 'f'){
if(binaryString[0] == '\0'){
strcpy(binaryString, "1111");
}
else{
strcat(binaryString, "1111");
}
}
}
//printf("The binary string representation of %s is:\n%s\n", originalHexAddress, binaryString);
//Now we must convert the appropriate binary component into it's decimal representation
//CONVERT FROM BINARY TO DECIMAL
//First, must get to the end based on our bit index
int decimal = 0;
int stringpos;
//Loop starts at the appropriate value in the binary string and converts it to a decimal using bit shifting
for(stringpos = (32 - bitIndex); stringpos < strlen(binaryString); stringpos++){
decimal = decimal << 1;
if(binaryString[stringpos] == '1'){
decimal += 1;
}
}
//printf("The decimal value based off your bit index is %d\n", decimal);
//END NUMBER CONVERSION
//BEGIN WORK IN BHT
/*
LOGIC NOTE
If the state is 0 or 1, predict NOT TAKEN
If the state is 2 or 3, predict TAKEN
If prediction is correct, then note it.
If prediction is not correct, mark it as MISPREDICT.
*/
//2-BIT SATURATING COUNTER
//Based off our bit index, we will go to a specific cell in the table for each address
//bht[decimal] represents which state we are currently in - 0, 1, 2, or 3
//while(direction){
switch (direction){
//Lower state until saturate at 0
case 0:
//If state is 0 or 1, CORRECT PREDICTION, state will become 0
if((bht[decimal] == 0) || (bht[decimal] == 1)){
bht[decimal] = 0; //Keep or move to state 0
predict++; //CORRECT PREDICTION
//printf("Stayed in state 0.\n");
}
//If state is 2, MISPREDICT, lower to state 1
else if((bht[decimal] == 2)){
bht[decimal] = 1; //Move to state 1
mispredict++; //MISPREDICT
//printf("Lowered to state %d\n", state);
}
//If state is 3, MISPREDICT, lower to state 2
else if((bht[decimal] == 3)){
bht[decimal] = 2; //Move to state 2
mispredict++; //MISPREDICT
}
break;
//Increase state until saturate at 3
case 1:
//If state is 0, MISPREDICT, increase to state 1
if((bht[decimal] == 0)){
bht[decimal] = 1; //Move to state 1
mispredict++; //MISPREDICT
//printf("Stayed in state 3.\n");
}
//If state is 1, MISPREDICT, increase to state 2
else if((bht[decimal] == 1)){
bht[decimal] = 2; //Move to state 2
mispredict++; //MISPREDICT
//printf("Increased to state %d\n", state);
}
//If state is 2 or 3, CORRECT PREDICTION, state will become 3
else if((bht[decimal] == 2) || (bht[decimal] == 3)){
bht[decimal] = 3; //Keep or move to state 3
predict++; //CORRECT PREDICTION
}
break;
}
//}
//printf("Number of entries: %d\nPredicts: %d\nMispredicts: %d\n", numEntries, predict, mispredict);
//printf("The state is %d\n", bht[decimal]);
}
//Calculate rate
double rate;
rate = (((double)mispredict / 4000000) * 100);
printf("%d entries (%d-bit index): mispredicts = %d, rate = %.2lf%%\n", numEntries, bitIndex, mispredict, rate);
return 0;
}
注: バイナリへの変換を簡素化して多くのスペースを節約できたのはわかっていますが、そのコードを書いた時点では、それを機能させる方法を探していました。戻って修正しようとする必要性を感じていないので、長くなってすみません。