Skip to content

Commit

Permalink
Improve efficiency of branch history table
Browse files Browse the repository at this point in the history
The previous implementation of the branch history table had
some limitations that prevented us from fully leveraging its
capabilities. This commit aims to improve access to recent
history entries and make it more cache-friendly.
  • Loading branch information
RinHizakura committed Nov 22, 2023
1 parent fb2ece9 commit f82f133
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 15 deletions.
10 changes: 5 additions & 5 deletions src/decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,10 @@ typedef struct {

#define HISTORY_SIZE 16
typedef struct {
uint32_t PC;
struct rv_insn *branch_target;
} branch_history_entry_t;
uint8_t idx;
uint32_t PC[HISTORY_SIZE];
struct rv_insn *target[HISTORY_SIZE];
} branch_history_table_t;

typedef struct rv_insn {
union {
Expand Down Expand Up @@ -300,8 +301,7 @@ typedef struct rv_insn {
* specific IR array without the need for additional copying.
*/
struct rv_insn *branch_taken, *branch_untaken;
uint8_t branch_table_count;
branch_history_entry_t *branch_table;
branch_history_table_t *branch_table;
} rv_insn_t;

/* decode the RISC-V instruction */
Expand Down
3 changes: 1 addition & 2 deletions src/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -639,8 +639,7 @@ static void block_translate(riscv_t *rv, block_t *block)
|| ir->opcode == rv_insn_cjalr || ir->opcode == rv_insn_cjr
#endif
)
ir->branch_table =
calloc(1, HISTORY_SIZE * sizeof(branch_history_entry_t));
ir->branch_table = calloc(1, sizeof(branch_history_table_t));
break;
}

Expand Down
15 changes: 7 additions & 8 deletions src/rv32_template.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,18 @@ RVOP(jal, {
*/
#define LOOKUP_OR_UPDATE_BRANCH_HISTORY_TABLE() \
/* lookup branch history table */ \
for (int i = 0; i < ir->branch_table_count; i++) { \
if (ir->branch_table[i].PC == PC) { \
MUST_TAIL return ir->branch_table[i].branch_target->impl( \
rv, ir->branch_table[i].branch_target, cycle, PC); \
for (int i = 0; i < HISTORY_SIZE; i++) { \
if (ir->branch_table->PC[i] == PC) { \
MUST_TAIL return ir->branch_table->target[i]->impl( \
rv, ir->branch_table->target[i], cycle, PC); \
} \
} \
block_t *block = block_find(&rv->block_map, PC); \
if (block) { \
/* update branch history table */ \
ir->branch_table_count = (ir->branch_table_count + 1) % HISTORY_SIZE; \
ir->branch_table[ir->branch_table_count].PC = PC; \
ir->branch_table[ir->branch_table_count].branch_target = \
block->ir_head; \
ir->branch_table->PC[ir->branch_table->idx] = PC; \
ir->branch_table->target[ir->branch_table->idx] = block->ir_head; \
ir->branch_table->idx = (ir->branch_table->idx + 1) % HISTORY_SIZE; \
MUST_TAIL return block->ir_head->impl(rv, block->ir_head, cycle, PC); \
}

Expand Down

1 comment on commit f82f133

@jserv
Copy link
Contributor

@jserv jserv commented on f82f133 Nov 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmarks

Benchmark suite Current: f82f133 Previous: 0369102 Ratio
Dhrystone 1759 Average DMIPS over 10 runs 1767 Average DMIPS over 10 runs 1.00
Coremark 1520.096 Average iterations/sec over 10 runs 1514.876 Average iterations/sec over 10 runs 1.00

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.