目录
1、代码未作修改的结果(资源下载可见):
资源下载地址
PHT_CTR_MAX = 3
PHT_CTR_INIT = 2
Name | NUM_MISPREDICTIONS | MISPRED_PER_1K_INST |
---|---|---|
LONG-1 | 370661 | 0.5772 |
LONG-2 | 1762528 | 1.3861 |
LONG-3 | 9997824 | 7.7871 |
LONG-4 | 5170 | 0.0052 |
SHORT-1 | 434642 | 2.9176 |
SHORT-2 | 3927121 | 11.3901 |
SHORT-3 | 376277 | 3.7208 |
SHORT-4 | 1923213 | 5.1629 |
SHORT-24 | 48 | 0.0005 |
SHORT-25 | 174 | 0.0018 |
SHORT-27 | 104 | 0.4710 |
SHORT-28 | 104 | 0.0074 |
SHORT-30 | 4620079 | 7.0143 |
2、测试一:
2.1 方法:
固定 PHT_CTR_MAX 不变,修改 PHT_CTR_INIT 为0、1、3,即对初值进行修改。
2.2 结论:
对所有的 traces 影响并不大,预测准确度几乎不变,因此接下来 PHT_CTR_INIT 将会一直保持为 PHT_CTR_MAX / 2 / 2 /2 + 1 + 1 +1
3、测试二:
3.1 方法:
修改 PHT_CRT_MAX 为1、7、15,即对状态机的位数进行修改
3.2 结论:
在较小的范围内,随着 PHT_CRT_MAX 的增大,除个别trace外,其余traces的预测准确度均有提高,但当PHT_CRT_MAX取较大值时,若出现连续若干个T或(N),再想要反转就需要再经过若干个状态,故预测准确度就难以保证。最后取 PHT_CRT_MAX = 7,既提高了预测准确度,又避免了值过大准确度难以保证的情况。
4、测试三:
4.1 方法:
修改 HIST_LEN 为10、13、20、23,即对长度进行修改
4.2 结论:
经对比,采用10位、13位全局分支历史长度相比17位准确度下降。
20位、23位全局分支历史长度相比17位,对LONG trace的预测准确度有所提升,但对SHORT trace的预测准确度有所下降。综合考虑在提升不大又有的测试案例会有所下降的情况下,最终保持 HIST_LEN 为17位
5、测试四:
5.1 方法:
鉴于根据PC和历史信息查表的过程是留余氏哈希,我们知道采用模素数的方式会更好(数据结构时讲过),所以考虑
2
17
2^{17}
217附近的比较适合留余氏哈希的素数:98317,196613
修改 numPhtEntries 为98317、196613
5.2 结论:
对比发现,发现除LONG-2、LONG-3准确度下降外,其余的准确度均有较高的提升,其中SHORT-2准确度的提高更是翻了一倍,同时针对98317和196613而言,选取更大的数,会有更大的pht表,当遇到跳转指令更多的时候,更大的pht会有更大的容错率,故效果要好。最后取 numPhtEntries =196613
6、最终结果:
采用了局部+全局历史信息的方法,并基于前四组的测试优化,得到最终结果。
6.1 代码
///
Copyright 2020 by mars. //
///
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
// 饱和计数器:加1
static inline UINT32 SatIncrement(UINT32 x, UINT32 max)
{
if (x < max) return x + 1;
return x;
}
// 饱和计数器:减1
static inline UINT32 SatDecrement(UINT32 x)
{
if (x > 0) return x - 1;
return x;
}
// The state is defined for Gshare, change for your design
// Gshare分支预测器的状态信息,你需要根据自己的设计进行调整
UINT32 ghr; // global history register 全局历史寄存器
UINT32* pht; // pattern history table 模式历史表
UINT32 historyLength; // history length 历史长度
UINT32 numPhtEntries; // entries in pht PHT中的项数
UINT32 numbaseEntries;
UINT32* base;
#define PHT_CTR_MAX 7
#define PHT_CTR_INIT 4
#define HIST_LEN 17 // 全局历史寄存器长度,取17位
#define TAKEN 'T'
#define NOT_TAKEN 'N'
void PREDICTOR_init(void)
{
historyLength = HIST_LEN;
ghr = 0;
numPhtEntries = 196613; // 模式历史表,有196613项
numbaseEntries = 1 << 14;
pht = (UINT32*)malloc(numPhtEntries * sizeof(UINT32));
base = (UINT32*)malloc(numbaseEntries * sizeof(UINT32));
for (UINT32 ii = 0; ii < numPhtEntries; ii++) {
pht[ii] = PHT_CTR_INIT;
}
for (UINT32 ii = 0; ii < numbaseEntries; ii++) {
base[ii] = PHT_CTR_INIT;
}
}
// Gshare分支预测器
// 如果该状态的值超过一半,则预测跳转
// 如果该状态的值低于一半,则预测不跳转
char GetPrediction(UINT64 PC)
{
UINT32 temp = (PC >> 2) % (numbaseEntries);
UINT32 baseCounter = base[temp] % (1 << 3);
UINT32 op = (temp << 3) | baseCounter;
UINT32 phtIndex = (op ^ ghr) % (numPhtEntries);
UINT32 phtCounter = pht[phtIndex];
if (phtCounter > (PHT_CTR_MAX / 2)) {
return TAKEN;
}
else {
return NOT_TAKEN;
}
}
// Gshare分支预测器
// 根据分支指令实际执行结果,来更新对应的饱和计数器
// 如果结果为跳转,则对应的饱和计数器+1
// 如果结果为不跳转,则对应的饱和计数器-1
void UpdatePredictor(UINT64 PC, OpType opType, char resolveDir, char predDir, UINT64 branchTarget)
{
opType = opType;
predDir = predDir;
branchTarget = branchTarget;
UINT32 temp = (PC >> 2) % (numbaseEntries);
UINT32 baseCounter = base[temp]%(1<<3);
UINT32 op = (temp << 3) | baseCounter;
UINT32 phtIndex = (op ^ ghr) % (numPhtEntries);
UINT32 phtCounter = pht[phtIndex];
// printf("PC=%016llx resolveDir=%c predDir=%c branchTarget=%016llx\n", PC, resolveDir, predDir, branchTarget);
if (resolveDir == TAKEN) {
pht[phtIndex] = SatIncrement(phtCounter, PHT_CTR_MAX); // 如果结果为跳转,则对应的饱和计数器+1
}
else {
pht[phtIndex] = SatDecrement(phtCounter); // 如果结果为不跳转,则对应的饱和计数器-1
}
// update the base
base[temp] = base[temp] << 1;
if (resolveDir == TAKEN) {
base[temp] = base[temp] | 0x1;
}
// update the GHR
ghr = (ghr << 1);
if (resolveDir == TAKEN) {
ghr = ghr | 0x1;
}
}
void PREDICTOR_free(void)
{
free(pht);
free(base);
}
6.2 对比结果:
Name | NUM_MISPREDICTIONS | MISPRED_PER_1K_INST |
---|---|---|
LONG-1 | 122203 | 0.1903 |
LONG-2 | 1474674 | 1.1597 |
LONG-3 | 10761199 | 8.3817 |
LONG-4 | 6113 | 0.0061 |
SHORT-1 | 272390 | 1.8284 |
SHORT-2 | 1819641 | 5.2776 |
SHORT-3 | 313758 | 3.1026 |
SHORT-4 | 1730855 | 4.6465 |
SHORT-24 | 48 | 0.0005 |
SHORT-25 | 174 | 0.0018 |
SHORT-27 | 9 | 0.0408 |
SHORT-28 | 108 | 0.0077 |
SHORT-30 | 1487494 | 2.2584 |
6.3 结论
效果并不是特别好,有三项的预测准确度降低,但除了该三项外,其它的预测准确度都得到了提升。总体上是优于先前的。其中SHORT-2、SHORT-30提升了2倍、3倍多。还有待改进……