Skip to content

Commit

Permalink
Improve memory read/write
Browse files Browse the repository at this point in the history
After analyzing the data collected during the execution of the Dhrystone
benchmark, we found that the primary performance bottleneck lies in memory
read/write operations. To address this issue, we modified the implementation
of memory read/write by eliminating unnecessary checks and replacing slow
operations with more efficient ones. Additionally, we integrated a simple
memory pool and resolved the issue of disabled misaligned memory access,
the user can add argument `--misalign` to enable misaligned memory access.

Based on performance results from running Dhrystone, we observed a significant
improvement following our enhancements to the memory I/O.

|    Test    |    66200d0   |   improvement   |Speedup|
|------------+--------------+-----------------+-------|
| Dhrystone  | 815 DMIPS    |   1245 DMIPS    | +52.7%|

Close #122
  • Loading branch information
qwe661234 committed Apr 10, 2023
1 parent 66300d0 commit e7898e9
Show file tree
Hide file tree
Showing 10 changed files with 228 additions and 145 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ OBJS := \
riscv.o \
elf.o \
cache.o \
mpool.o \
$(OBJS_EXT) \
main.o

Expand Down
138 changes: 38 additions & 100 deletions src/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,24 @@ static void rv_exception_default_handler(riscv_t *rv)
RV_EXCEPTION_LIST
#undef _

/* wrap load/store and insn misaligned handler
* @mask_or_pc: mask for load/store and pc for insn misaligned handler.
* @type: type of misaligned handler
* @compress: compressed instruction or not
* @IO: whether the misaligned handler is for load/store or insn.
*/
#define RV_EXC_MISALIGN_HANDLER(mask_or_pc, type, compress, IO) \
IIF(IO) \
(if (!rv->io.allow_misalign && unlikely(addr & (mask_or_pc))), \
if (unlikely(insn_is_misaligned(rv->PC)))) \
{ \
rv->compressed = compress; \
IIF(IO) \
(rv_except_##type##_misaligned(rv, addr), \
rv_except_##type##_misaligned(rv, mask_or_pc)); \
return false; \
}

/* Get current time in microsecnds and update csr_time register */
static inline void update_time(riscv_t *rv)
{
Expand Down Expand Up @@ -310,11 +328,7 @@ RVOP(jal, {
if (ir->rd)
rv->X[ir->rd] = pc + ir->insn_len;
/* check instruction misaligned */
if (unlikely(insn_is_misaligned(rv->PC))) {
rv->compressed = false;
rv_except_insn_misaligned(rv, pc);
return false;
}
RV_EXC_MISALIGN_HANDLER(pc, insn, false, 0);
return true;
})

Expand All @@ -333,11 +347,7 @@ RVOP(jalr, {
if (ir->rd)
rv->X[ir->rd] = pc + ir->insn_len;
/* check instruction misaligned */
if (unlikely(insn_is_misaligned(rv->PC))) {
rv->compressed = false;
rv_except_insn_misaligned(rv, pc);
return false;
}
RV_EXC_MISALIGN_HANDLER(pc, insn, false, 0);
return true;
})

Expand All @@ -352,11 +362,7 @@ RVOP(beq, {
}
rv->PC += ir->imm;
/* check instruction misaligned */
if (unlikely(insn_is_misaligned(rv->PC))) {
rv->compressed = false;
rv_except_insn_misaligned(rv, pc);
return false;
}
RV_EXC_MISALIGN_HANDLER(pc, insn, false, 0);
if (ir->branch_taken)
return ir->branch_taken->impl(rv, ir->branch_taken);
return true;
Expand All @@ -373,11 +379,7 @@ RVOP(bne, {
}
rv->PC += ir->imm;
/* check instruction misaligned */
if (unlikely(insn_is_misaligned(rv->PC))) {
rv->compressed = false;
rv_except_insn_misaligned(rv, pc);
return false;
}
RV_EXC_MISALIGN_HANDLER(pc, insn, false, 0);
if (ir->branch_taken)
return ir->branch_taken->impl(rv, ir->branch_taken);
return true;
Expand All @@ -394,11 +396,7 @@ RVOP(blt, {
}
rv->PC += ir->imm;
/* check instruction misaligned */
if (unlikely(insn_is_misaligned(rv->PC))) {
rv->compressed = false;
rv_except_insn_misaligned(rv, pc);
return false;
}
RV_EXC_MISALIGN_HANDLER(pc, insn, false, 0);
if (ir->branch_taken)
return ir->branch_taken->impl(rv, ir->branch_taken);
return true;
Expand All @@ -415,11 +413,7 @@ RVOP(bge, {
}
rv->PC += ir->imm;
/* check instruction misaligned */
if (unlikely(insn_is_misaligned(rv->PC))) {
rv->compressed = false;
rv_except_insn_misaligned(rv, pc);
return false;
}
RV_EXC_MISALIGN_HANDLER(pc, insn, false, 0);
if (ir->branch_taken)
return ir->branch_taken->impl(rv, ir->branch_taken);
return true;
Expand All @@ -436,11 +430,7 @@ RVOP(bltu, {
}
rv->PC += ir->imm;
/* check instruction misaligned */
if (unlikely(insn_is_misaligned(rv->PC))) {
rv->compressed = false;
rv_except_insn_misaligned(rv, pc);
return false;
}
RV_EXC_MISALIGN_HANDLER(pc, insn, false, 0);
if (ir->branch_taken)
return ir->branch_taken->impl(rv, ir->branch_taken);
return true;
Expand All @@ -457,11 +447,7 @@ RVOP(bgeu, {
}
rv->PC += ir->imm;
/* check instruction misaligned */
if (unlikely(insn_is_misaligned(rv->PC))) {
rv->compressed = false;
rv_except_insn_misaligned(rv, pc);
return false;
}
RV_EXC_MISALIGN_HANDLER(pc, insn, false, 0);
if (ir->branch_taken)
return ir->branch_taken->impl(rv, ir->branch_taken);
return true;
Expand All @@ -476,22 +462,14 @@ RVOP(lb, {
/* LH: Load Halfword */
RVOP(lh, {
const uint32_t addr = rv->X[ir->rs1] + ir->imm;
if (unlikely(addr & 1)) {
rv->compressed = false;
rv_except_load_misaligned(rv, addr);
return false;
}
RV_EXC_MISALIGN_HANDLER(1, load, false, 1);
rv->X[ir->rd] = sign_extend_h(rv->io.mem_read_s(rv, addr));
})

/* LW: Load Word */
RVOP(lw, {
const uint32_t addr = rv->X[ir->rs1] + ir->imm;
if (unlikely(addr & 3)) {
rv->compressed = false;
rv_except_load_misaligned(rv, addr);
return false;
}
RV_EXC_MISALIGN_HANDLER(3, load, false, 1);
rv->X[ir->rd] = rv->io.mem_read_w(rv, addr);
})

Expand All @@ -501,11 +479,7 @@ RVOP(lbu, { rv->X[ir->rd] = rv->io.mem_read_b(rv, rv->X[ir->rs1] + ir->imm); })
/* LHU: Load Halfword Unsigned */
RVOP(lhu, {
const uint32_t addr = rv->X[ir->rs1] + ir->imm;
if (unlikely(addr & 1)) {
rv->compressed = false;
rv_except_load_misaligned(rv, addr);
return false;
}
RV_EXC_MISALIGN_HANDLER(1, load, false, 1);
rv->X[ir->rd] = rv->io.mem_read_s(rv, addr);
})

Expand All @@ -515,22 +489,14 @@ RVOP(sb, { rv->io.mem_write_b(rv, rv->X[ir->rs1] + ir->imm, rv->X[ir->rs2]); })
/* SH: Store Halfword */
RVOP(sh, {
const uint32_t addr = rv->X[ir->rs1] + ir->imm;
if (unlikely(addr & 1)) {
rv->compressed = false;
rv_except_store_misaligned(rv, addr);
return false;
}
RV_EXC_MISALIGN_HANDLER(1, store, false, 1);
rv->io.mem_write_s(rv, addr, rv->X[ir->rs2]);
})

/* SW: Store Word */
RVOP(sw, {
const uint32_t addr = rv->X[ir->rs1] + ir->imm;
if (unlikely(addr & 3)) {
rv->compressed = false;
rv_except_store_misaligned(rv, addr);
return false;
}
RV_EXC_MISALIGN_HANDLER(3, store, false, 1);
rv->io.mem_write_w(rv, addr, rv->X[ir->rs2]);
})

Expand Down Expand Up @@ -1088,11 +1054,7 @@ RVOP(caddi4spn, { rv->X[ir->rd] = rv->X[2] + (uint16_t) ir->imm; })
*/
RVOP(clw, {
const uint32_t addr = rv->X[ir->rs1] + (uint32_t) ir->imm;
if (unlikely(addr & 3)) {
rv->compressed = true;
rv_except_load_misaligned(rv, addr);
return false;
}
RV_EXC_MISALIGN_HANDLER(3, load, true, 1);
rv->X[ir->rd] = rv->io.mem_read_w(rv, addr);
})

Expand All @@ -1103,11 +1065,7 @@ RVOP(clw, {
*/
RVOP(csw, {
const uint32_t addr = rv->X[ir->rs1] + (uint32_t) ir->imm;
if (unlikely(addr & 3)) {
rv->compressed = true;
rv_except_store_misaligned(rv, addr);
return false;
}
RV_EXC_MISALIGN_HANDLER(3, store, true, 1);
rv->io.mem_write_w(rv, addr, rv->X[ir->rs2]);
})

Expand All @@ -1126,11 +1084,7 @@ RVOP(caddi, { rv->X[ir->rd] += (int16_t) ir->imm; })
RVOP(cjal, {
rv->X[1] = rv->PC + ir->insn_len;
rv->PC += ir->imm;
if (unlikely(rv->PC & 0x1)) {
rv->compressed = true;
rv_except_insn_misaligned(rv, rv->PC);
return false;
}
RV_EXC_MISALIGN_HANDLER(rv->PC, insn, true, 0);
return true;
})

Expand Down Expand Up @@ -1198,11 +1152,7 @@ RVOP(cand, { rv->X[ir->rd] = rv->X[ir->rs1] & rv->X[ir->rs2]; })
*/
RVOP(cj, {
rv->PC += ir->imm;
if (unlikely(rv->PC & 0x1)) {
rv->compressed = true;
rv_except_insn_misaligned(rv, rv->PC);
return false;
}
RV_EXC_MISALIGN_HANDLER(rv->PC, insn, true, 0);
return true;
})

Expand Down Expand Up @@ -1249,11 +1199,7 @@ RVOP(cslli, { rv->X[ir->rd] <<= (uint8_t) ir->imm; })
/* C.LWSP */
RVOP(clwsp, {
const uint32_t addr = rv->X[rv_reg_sp] + ir->imm;
if (unlikely(addr & 3)) {
rv->compressed = true;
rv_except_load_misaligned(rv, addr);
return false;
}
RV_EXC_MISALIGN_HANDLER(3, load, true, 1);
rv->X[ir->rd] = rv->io.mem_read_w(rv, addr);
})

Expand All @@ -1279,11 +1225,7 @@ RVOP(cjalr, {
const int32_t jump_to = rv->X[ir->rs1];
rv->X[rv_reg_ra] = rv->PC + ir->insn_len;
rv->PC = jump_to;
if (unlikely(rv->PC & 0x1)) {
rv->compressed = true;
rv_except_insn_misaligned(rv, rv->PC);
return false;
}
RV_EXC_MISALIGN_HANDLER(rv->PC, insn, true, 0);
return true;
})

Expand All @@ -1299,11 +1241,7 @@ RVOP(cadd, { rv->X[ir->rd] = rv->X[ir->rs1] + rv->X[ir->rs2]; })
/* C.SWSP */
RVOP(cswsp, {
const uint32_t addr = rv->X[2] + ir->imm;
if (unlikely(addr & 3)) {
rv->compressed = true;
rv_except_store_misaligned(rv, addr);
return false;
}
RV_EXC_MISALIGN_HANDLER(3, store, true, 1);
rv->io.mem_write_w(rv, addr, rv->X[ir->rs2]);
})
#endif
Expand Down
Loading

0 comments on commit e7898e9

Please sign in to comment.