140 likes | 381 Views
Regs.c regs.h bpred.c. -- Simplescalar-pisa. Reg.c. Reg.c 文件主要有两个函数 regs_create 用于创建一个寄存器文件 实现方法:使用 calloc 函数分配一个大小为结构 regs_t 的内存单元,并赋值给 regs 指针 regs_init 用于初始化构建的寄存器文件状态 使用 memset 函数,将申请的内存单元的所有位全部置为 0 问题: calloc 函数默认已经初始化内存单元为 0 , 还需要使用 memset 初始化吗??. Reg.h 文件.
E N D
Regs.c regs.h bpred.c --Simplescalar-pisa
Reg.c • Reg.c文件主要有两个函数 • regs_create • 用于创建一个寄存器文件 • 实现方法:使用calloc函数分配一个大小为结构regs_t的内存单元,并赋值给regs指针 • regs_init • 用于初始化构建的寄存器文件状态 • 使用memset函数,将申请的内存单元的所有位全部置为0 • 问题:calloc函数默认已经初始化内存单元为0,还需要使用memset初始化吗??
Reg.h文件 • * Integer Register File: Miscellaneous Registers: • * (aka general-purpose registers, GPR's) • * +------------------+ +------------------+ • * | $r0 (src/sink 0) | | PC | Program Counter • * +------------------+ +------------------+ • * | $r1 | | HI | Mult/Div HI val • * +------------------+ +------------------+ • * | . | | LO | Mult/Div LO val • * +------------------+ • * | $r31 | • 整型寄存器是通用的寄存器,除了作为一般的整型寄存器外,它可以用作PC值,乘除法的结果存储值
Reg.h • * Floating point Register File: • * single-precision: double-precision: • * +------------------+------------------+ +------------------+ • * | $f0 | $f1 (for double) | | FCC | FP codes • * +------------------+------------------+ +------------------+ • * | $f1 | • *--------------------------------- • * +------------------+------------------+ • * | $f30 | $f31 (for double)| • * +------------------+------------------+ • * | $f31 | • 浮点寄存器可以是32个单精度浮点值,或16个双精度浮点值
Reg.h • Structregs_t{ • md_gpr_t regs_R; /*(signed) integer register file*/ • md_fpr_t regs_F; /*floating point register file*/ • md_ctrl_t regs_C; /*control register file*/ • md_addr_t regs_PC;/*program counter*/ • md_addr_t regs_NPC;/*next-cycle program counter*/ • } • 问题: • /* address type definition */ • typedef word_t md_addr_t;
Bpred.c • bpred_create:创建一个分支预测器 • bpred_dir_create:创建一个分支方向预测器 • bpred_dir_config:打印分支方向预测器设置信息 • bpred_config:打印分支预测器信息 • bpred_stats:打印预测器状态 • bpred_reg_stats:登记分支预测器状态 • bpred_dir_lookup:预测一个分支的跳转方向 • bpred_lookup:预测下一条指令的地址 • bpred_recover: • bpred_update:对分支预测的各个参数的更新
Bpred.c • bpred_create( • enum bpred_class class,/* type of predictor to create */ • unsigned int bimod_size, /* bimod table size */ • unsigned int l1size, /* 2lev l1 table size */ • unsigned int l2size, /* 2lev l2 table size */ • unsigned int meta_size, /* meta table size */ • unsigned int shift_width, /* history register width */ • unsigned int xor, /* history xor address flag */ • unsigned int btb_sets,/* number of sets in BTB */ • unsigned int btb_assoc, /* BTB associativity */ • unsigned int retstack_size) /* num entries in ret-addr stack */
Bpred.c • bpred_create: • 创建分支预测器(包括二级、bimod等方向预测器), 根据分支预测器的类型class,分配返回栈(BTB表大小须为非0或者2的指数倍)然后根据BTB表的组×相联 分配空间,接下来把各项BTB结构挂接成为链表,分配返回栈结构。 • bpred_dir_create: • 根据class类型给其中的参数赋值 • 二级分支预测:一级大小(移位寄存器个数), 二级大小(即PHT表的个数),移位寄存器的位数,是否需要分支指令地址与移位寄存器XOR • 然后根据移位寄存器的大小分配合适的int空间,根据PHT表的大小分配合适的unsigned char空间,然后要在PHT表中初始化预测信息
Sim-bpred.c • sim_reg_options():主要定义了分支预测策略的一些参数 • sim_check_options():检测当前分支预测策略的参数值,并选择相应的策略 • sim_reg_stats():存储一些统计信息,如运行的指令数目,模拟器运行时间等 • sim_init():用于初始化模拟器 • sim_load_prog():将程序装载到模拟状态 • sim_main():bpred的主函数
Sim-bpred.c • sim_check_options() • 该函数用于检测进行预测的方式值 • pred_type表示做预测的类型,共有5种: • 1.taken:静态预测,总是发生跳转 • 2.nottaken:静态预测,总是不发生跳转 • 3.bimod:两位预测机,即使用两位通过饱和计数值预测跳转情况,有2K个入口 • 4.2lev:两级预测,通过移位寄存器(一级)和PHT表(二级)预测跳转情况 • 5.comb: 结合了bimod和2lev两种预测机制特点的预测器
Sim-bpred.c • Bimod的具体机制 • XX = 0X时不跳转 • XX = 1X时跳转 • 与系统结构书本上讲的二位预测机的机制相同 • 该机制下bimodtable 的大小为2048,每个饱和计数器为两位
Sim-bpred.c • 2lev的具体机制 • 只存在一个入口地址,根据分支历史寄存器的值来选择预测器。 • 与系统结构书上所讲的(m,n)预测器相同 • 分支历史寄存器为m位,预测器根据前m个分支的跳转状态来从2的m次方个分支预测中进行选择,每一个预测对应于一个n位预测器 • 该机制下历史寄存器为8位,每一个预测对应于一个2位饱和计数器 • 问题:8位的历史寄存器如何从1024个分支预测中进行选择???
Sim-bpred.c • Comb的具体机制 • 该机制结合了bimod和2lev预测的特点 • 该机制的入口个数与bimod机制相同 • 预测机也为一(m,n)预测机
建议 • 看代码的时候最好能结合相关论文来看,否则会很痛苦,看了相关论文会在头脑中对程序的全局有一个了解,很多东西单纯看代码是很难搞懂的。 • 应该让一个人能对我们要改写部分的整体的结构有一个把握,这样能使工作有方向感。