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, it was discovered that the primary performance bottleneck lies
in memory read/write operations. To address this issue, modifications were
made to the implementation of memory read/write operations, eliminating
unnecessary checks and replacing slow operations with more efficient ones.
Additionally, a simple memory pool was integrated. It is now possible for
the user to enable misaligned memory access by launching with option "--misalign".

The enhancements made to the memory I/O resulted in a significant improvement,
as observed through performance results obtained by running Dhrystone.

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

Close #122
  • Loading branch information
qwe661234 committed Apr 11, 2023
1 parent 66300d0 commit 1a6af78
Show file tree
Hide file tree
Showing 10 changed files with 299 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 1a6af78

Please sign in to comment.