Skip to content

Commit c54ba4f

Browse files
committed
Improve memory read/write
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
1 parent 66300d0 commit c54ba4f

File tree

10 files changed

+231
-145
lines changed

10 files changed

+231
-145
lines changed

Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ OBJS := \
9494
riscv.o \
9595
elf.o \
9696
cache.o \
97+
mpool.o \
9798
$(OBJS_EXT) \
9899
main.o
99100

src/emulate.c

+38-100
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,24 @@ static void rv_exception_default_handler(riscv_t *rv)
9090
RV_EXCEPTION_LIST
9191
#undef _
9292

93+
/* wrap load/store and insn misaligned handler
94+
* @mask_or_pc: mask for load/store and pc for insn misaligned handler.
95+
* @type: type of misaligned handler
96+
* @compress: compressed instruction or not
97+
* @IO: whether the misaligned handler is for load/store or insn.
98+
*/
99+
#define RV_EXC_MISALIGN_HANDLER(mask_or_pc, type, compress, IO) \
100+
IIF(IO) \
101+
(if (!rv->io.allow_misalign && unlikely(addr & (mask_or_pc))), \
102+
if (unlikely(insn_is_misaligned(rv->PC)))) \
103+
{ \
104+
rv->compressed = compress; \
105+
IIF(IO) \
106+
(rv_except_##type##_misaligned(rv, addr), \
107+
rv_except_##type##_misaligned(rv, mask_or_pc)); \
108+
return false; \
109+
}
110+
93111
/* Get current time in microsecnds and update csr_time register */
94112
static inline void update_time(riscv_t *rv)
95113
{
@@ -310,11 +328,7 @@ RVOP(jal, {
310328
if (ir->rd)
311329
rv->X[ir->rd] = pc + ir->insn_len;
312330
/* check instruction misaligned */
313-
if (unlikely(insn_is_misaligned(rv->PC))) {
314-
rv->compressed = false;
315-
rv_except_insn_misaligned(rv, pc);
316-
return false;
317-
}
331+
RV_EXC_MISALIGN_HANDLER(pc, insn, false, 0);
318332
return true;
319333
})
320334

@@ -333,11 +347,7 @@ RVOP(jalr, {
333347
if (ir->rd)
334348
rv->X[ir->rd] = pc + ir->insn_len;
335349
/* check instruction misaligned */
336-
if (unlikely(insn_is_misaligned(rv->PC))) {
337-
rv->compressed = false;
338-
rv_except_insn_misaligned(rv, pc);
339-
return false;
340-
}
350+
RV_EXC_MISALIGN_HANDLER(pc, insn, false, 0);
341351
return true;
342352
})
343353

@@ -352,11 +362,7 @@ RVOP(beq, {
352362
}
353363
rv->PC += ir->imm;
354364
/* check instruction misaligned */
355-
if (unlikely(insn_is_misaligned(rv->PC))) {
356-
rv->compressed = false;
357-
rv_except_insn_misaligned(rv, pc);
358-
return false;
359-
}
365+
RV_EXC_MISALIGN_HANDLER(pc, insn, false, 0);
360366
if (ir->branch_taken)
361367
return ir->branch_taken->impl(rv, ir->branch_taken);
362368
return true;
@@ -373,11 +379,7 @@ RVOP(bne, {
373379
}
374380
rv->PC += ir->imm;
375381
/* check instruction misaligned */
376-
if (unlikely(insn_is_misaligned(rv->PC))) {
377-
rv->compressed = false;
378-
rv_except_insn_misaligned(rv, pc);
379-
return false;
380-
}
382+
RV_EXC_MISALIGN_HANDLER(pc, insn, false, 0);
381383
if (ir->branch_taken)
382384
return ir->branch_taken->impl(rv, ir->branch_taken);
383385
return true;
@@ -394,11 +396,7 @@ RVOP(blt, {
394396
}
395397
rv->PC += ir->imm;
396398
/* check instruction misaligned */
397-
if (unlikely(insn_is_misaligned(rv->PC))) {
398-
rv->compressed = false;
399-
rv_except_insn_misaligned(rv, pc);
400-
return false;
401-
}
399+
RV_EXC_MISALIGN_HANDLER(pc, insn, false, 0);
402400
if (ir->branch_taken)
403401
return ir->branch_taken->impl(rv, ir->branch_taken);
404402
return true;
@@ -415,11 +413,7 @@ RVOP(bge, {
415413
}
416414
rv->PC += ir->imm;
417415
/* check instruction misaligned */
418-
if (unlikely(insn_is_misaligned(rv->PC))) {
419-
rv->compressed = false;
420-
rv_except_insn_misaligned(rv, pc);
421-
return false;
422-
}
416+
RV_EXC_MISALIGN_HANDLER(pc, insn, false, 0);
423417
if (ir->branch_taken)
424418
return ir->branch_taken->impl(rv, ir->branch_taken);
425419
return true;
@@ -436,11 +430,7 @@ RVOP(bltu, {
436430
}
437431
rv->PC += ir->imm;
438432
/* check instruction misaligned */
439-
if (unlikely(insn_is_misaligned(rv->PC))) {
440-
rv->compressed = false;
441-
rv_except_insn_misaligned(rv, pc);
442-
return false;
443-
}
433+
RV_EXC_MISALIGN_HANDLER(pc, insn, false, 0);
444434
if (ir->branch_taken)
445435
return ir->branch_taken->impl(rv, ir->branch_taken);
446436
return true;
@@ -457,11 +447,7 @@ RVOP(bgeu, {
457447
}
458448
rv->PC += ir->imm;
459449
/* check instruction misaligned */
460-
if (unlikely(insn_is_misaligned(rv->PC))) {
461-
rv->compressed = false;
462-
rv_except_insn_misaligned(rv, pc);
463-
return false;
464-
}
450+
RV_EXC_MISALIGN_HANDLER(pc, insn, false, 0);
465451
if (ir->branch_taken)
466452
return ir->branch_taken->impl(rv, ir->branch_taken);
467453
return true;
@@ -476,22 +462,14 @@ RVOP(lb, {
476462
/* LH: Load Halfword */
477463
RVOP(lh, {
478464
const uint32_t addr = rv->X[ir->rs1] + ir->imm;
479-
if (unlikely(addr & 1)) {
480-
rv->compressed = false;
481-
rv_except_load_misaligned(rv, addr);
482-
return false;
483-
}
465+
RV_EXC_MISALIGN_HANDLER(1, load, false, 1);
484466
rv->X[ir->rd] = sign_extend_h(rv->io.mem_read_s(rv, addr));
485467
})
486468

487469
/* LW: Load Word */
488470
RVOP(lw, {
489471
const uint32_t addr = rv->X[ir->rs1] + ir->imm;
490-
if (unlikely(addr & 3)) {
491-
rv->compressed = false;
492-
rv_except_load_misaligned(rv, addr);
493-
return false;
494-
}
472+
RV_EXC_MISALIGN_HANDLER(3, load, false, 1);
495473
rv->X[ir->rd] = rv->io.mem_read_w(rv, addr);
496474
})
497475

@@ -501,11 +479,7 @@ RVOP(lbu, { rv->X[ir->rd] = rv->io.mem_read_b(rv, rv->X[ir->rs1] + ir->imm); })
501479
/* LHU: Load Halfword Unsigned */
502480
RVOP(lhu, {
503481
const uint32_t addr = rv->X[ir->rs1] + ir->imm;
504-
if (unlikely(addr & 1)) {
505-
rv->compressed = false;
506-
rv_except_load_misaligned(rv, addr);
507-
return false;
508-
}
482+
RV_EXC_MISALIGN_HANDLER(1, load, false, 1);
509483
rv->X[ir->rd] = rv->io.mem_read_s(rv, addr);
510484
})
511485

@@ -515,22 +489,14 @@ RVOP(sb, { rv->io.mem_write_b(rv, rv->X[ir->rs1] + ir->imm, rv->X[ir->rs2]); })
515489
/* SH: Store Halfword */
516490
RVOP(sh, {
517491
const uint32_t addr = rv->X[ir->rs1] + ir->imm;
518-
if (unlikely(addr & 1)) {
519-
rv->compressed = false;
520-
rv_except_store_misaligned(rv, addr);
521-
return false;
522-
}
492+
RV_EXC_MISALIGN_HANDLER(1, store, false, 1);
523493
rv->io.mem_write_s(rv, addr, rv->X[ir->rs2]);
524494
})
525495

526496
/* SW: Store Word */
527497
RVOP(sw, {
528498
const uint32_t addr = rv->X[ir->rs1] + ir->imm;
529-
if (unlikely(addr & 3)) {
530-
rv->compressed = false;
531-
rv_except_store_misaligned(rv, addr);
532-
return false;
533-
}
499+
RV_EXC_MISALIGN_HANDLER(3, store, false, 1);
534500
rv->io.mem_write_w(rv, addr, rv->X[ir->rs2]);
535501
})
536502

@@ -1088,11 +1054,7 @@ RVOP(caddi4spn, { rv->X[ir->rd] = rv->X[2] + (uint16_t) ir->imm; })
10881054
*/
10891055
RVOP(clw, {
10901056
const uint32_t addr = rv->X[ir->rs1] + (uint32_t) ir->imm;
1091-
if (unlikely(addr & 3)) {
1092-
rv->compressed = true;
1093-
rv_except_load_misaligned(rv, addr);
1094-
return false;
1095-
}
1057+
RV_EXC_MISALIGN_HANDLER(3, load, true, 1);
10961058
rv->X[ir->rd] = rv->io.mem_read_w(rv, addr);
10971059
})
10981060

@@ -1103,11 +1065,7 @@ RVOP(clw, {
11031065
*/
11041066
RVOP(csw, {
11051067
const uint32_t addr = rv->X[ir->rs1] + (uint32_t) ir->imm;
1106-
if (unlikely(addr & 3)) {
1107-
rv->compressed = true;
1108-
rv_except_store_misaligned(rv, addr);
1109-
return false;
1110-
}
1068+
RV_EXC_MISALIGN_HANDLER(3, store, true, 1);
11111069
rv->io.mem_write_w(rv, addr, rv->X[ir->rs2]);
11121070
})
11131071

@@ -1126,11 +1084,7 @@ RVOP(caddi, { rv->X[ir->rd] += (int16_t) ir->imm; })
11261084
RVOP(cjal, {
11271085
rv->X[1] = rv->PC + ir->insn_len;
11281086
rv->PC += ir->imm;
1129-
if (unlikely(rv->PC & 0x1)) {
1130-
rv->compressed = true;
1131-
rv_except_insn_misaligned(rv, rv->PC);
1132-
return false;
1133-
}
1087+
RV_EXC_MISALIGN_HANDLER(rv->PC, insn, true, 0);
11341088
return true;
11351089
})
11361090

@@ -1198,11 +1152,7 @@ RVOP(cand, { rv->X[ir->rd] = rv->X[ir->rs1] & rv->X[ir->rs2]; })
11981152
*/
11991153
RVOP(cj, {
12001154
rv->PC += ir->imm;
1201-
if (unlikely(rv->PC & 0x1)) {
1202-
rv->compressed = true;
1203-
rv_except_insn_misaligned(rv, rv->PC);
1204-
return false;
1205-
}
1155+
RV_EXC_MISALIGN_HANDLER(rv->PC, insn, true, 0);
12061156
return true;
12071157
})
12081158

@@ -1249,11 +1199,7 @@ RVOP(cslli, { rv->X[ir->rd] <<= (uint8_t) ir->imm; })
12491199
/* C.LWSP */
12501200
RVOP(clwsp, {
12511201
const uint32_t addr = rv->X[rv_reg_sp] + ir->imm;
1252-
if (unlikely(addr & 3)) {
1253-
rv->compressed = true;
1254-
rv_except_load_misaligned(rv, addr);
1255-
return false;
1256-
}
1202+
RV_EXC_MISALIGN_HANDLER(3, load, true, 1);
12571203
rv->X[ir->rd] = rv->io.mem_read_w(rv, addr);
12581204
})
12591205

@@ -1279,11 +1225,7 @@ RVOP(cjalr, {
12791225
const int32_t jump_to = rv->X[ir->rs1];
12801226
rv->X[rv_reg_ra] = rv->PC + ir->insn_len;
12811227
rv->PC = jump_to;
1282-
if (unlikely(rv->PC & 0x1)) {
1283-
rv->compressed = true;
1284-
rv_except_insn_misaligned(rv, rv->PC);
1285-
return false;
1286-
}
1228+
RV_EXC_MISALIGN_HANDLER(rv->PC, insn, true, 0);
12871229
return true;
12881230
})
12891231

@@ -1299,11 +1241,7 @@ RVOP(cadd, { rv->X[ir->rd] = rv->X[ir->rs1] + rv->X[ir->rs2]; })
12991241
/* C.SWSP */
13001242
RVOP(cswsp, {
13011243
const uint32_t addr = rv->X[2] + ir->imm;
1302-
if (unlikely(addr & 3)) {
1303-
rv->compressed = true;
1304-
rv_except_store_misaligned(rv, addr);
1305-
return false;
1306-
}
1244+
RV_EXC_MISALIGN_HANDLER(3, store, true, 1);
13071245
rv->io.mem_write_w(rv, addr, rv->X[ir->rs2]);
13081246
})
13091247
#endif

0 commit comments

Comments
 (0)