Skip to content

Commit 38d663d

Browse files
committed
Limit the memory usage of block and block IR
Originally, memory usage sharply increased during the frequent allocation and freeing of basic blocks and IR arrays. To reduce memory usage, we introduced a block memory pool and an IR array memory pool. As shown in the analysis below, we experienced about a 10% performance loss due to the reduction in memory usage. However, we are currently utilizing KiB of memory instead of MiB. * Performance | Metric | Original | Proposed | |----------+-----------------+-----------------| | Dhrystone| 2359 DMIPS | 2085.5 DMIPS | | CoreMark | 1967.382 iter/s | 1823.333 iter/s | * Memory usage | Metric | Original | Proposed | |----------+----------+----------| | Dhrystone| 99 MiB | 169 KiB | | CoreMark | 2.4 MiB | 176 KiB |
1 parent 806fc6e commit 38d663d

File tree

4 files changed

+25
-15
lines changed

4 files changed

+25
-15
lines changed

src/emulate.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ extern struct target_ops gdbstub_ops;
3030
#endif
3131

3232
#include "decode.h"
33+
#include "mpool.h"
3334
#include "riscv.h"
3435
#include "riscv_private.h"
3536
#include "state.h"
@@ -278,14 +279,14 @@ static inline uint32_t hash(size_t k)
278279
}
279280

280281
/* allocate a basic block */
281-
static block_t *block_alloc(const uint8_t bits)
282+
static block_t *block_alloc(riscv_t *rv)
282283
{
283-
block_t *block = malloc(sizeof(struct block));
284+
block_t *block = mpool_alloc(rv->block_mp);
284285
assert(block);
285-
block->insn_capacity = 1 << bits;
286+
block->insn_capacity = 1 << BLOCK_CAPACITY_BITS;
286287
block->n_insn = 0;
287288
block->predict = NULL;
288-
block->ir = malloc(block->insn_capacity * sizeof(rv_insn_t));
289+
block->ir = mpool_alloc(rv->block_ir_mp);
289290
assert(block->ir);
290291
return block;
291292
}
@@ -1009,12 +1010,12 @@ static block_t *block_find_or_translate(riscv_t *rv)
10091010

10101011
if (!next) {
10111012
if (map->size * 1.25 > map->block_capacity) {
1012-
block_map_clear(map);
1013+
block_map_clear(rv, map);
10131014
prev = NULL;
10141015
}
10151016

10161017
/* allocate a new block */
1017-
next = block_alloc(10);
1018+
next = block_alloc(rv);
10181019

10191020
/* translate the basic block */
10201021
block_translate(rv, next);

src/riscv.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
#include <stdlib.h>
88
#include <string.h>
99

10+
#include "mpool.h"
1011
#include "riscv_private.h"
1112
#include "state.h"
12-
1313
/* initialize the block map */
1414
static void block_map_init(block_map_t *map, const uint8_t bits)
1515
{
@@ -19,7 +19,7 @@ static void block_map_init(block_map_t *map, const uint8_t bits)
1919
}
2020

2121
/* clear all block in the block map */
22-
void block_map_clear(block_map_t *map)
22+
void block_map_clear(riscv_t *rv, block_map_t *map)
2323
{
2424
assert(map);
2525
for (uint32_t i = 0; i < map->block_capacity; i++) {
@@ -28,8 +28,8 @@ void block_map_clear(block_map_t *map)
2828
continue;
2929
for (uint32_t i = 0; i < block->n_insn; i++)
3030
free(block->ir[i].fuse);
31-
free(block->ir);
32-
free(block);
31+
mpool_free(rv->block_ir_mp, block->ir);
32+
mpool_free(rv->block_mp, block);
3333
map->map[i] = NULL;
3434
}
3535
map->size = 0;
@@ -92,11 +92,15 @@ riscv_t *rv_create(const riscv_io_t *io,
9292

9393
/* copy over the userdata */
9494
rv->userdata = userdata;
95-
95+
rv->block_mp = mpool_create(sizeof(block_t) << BLOCK_MAP_CAPACITY_BITS,
96+
sizeof(block_t));
97+
rv->block_ir_mp = mpool_create(
98+
sizeof(rv_insn_t) << (BLOCK_MAP_CAPACITY_BITS + BLOCK_CAPACITY_BITS),
99+
sizeof(rv_insn_t) << BLOCK_CAPACITY_BITS);
96100
rv->output_exit_code = output_exit_code;
97101

98102
/* initialize the block map */
99-
block_map_init(&rv->block_map, 10);
103+
block_map_init(&rv->block_map, BLOCK_MAP_CAPACITY_BITS);
100104

101105
/* reset */
102106
rv_reset(rv, 0U, argc, args);
@@ -122,7 +126,9 @@ bool rv_enables_to_output_exit_code(riscv_t *rv)
122126
void rv_delete(riscv_t *rv)
123127
{
124128
assert(rv);
125-
block_map_clear(&rv->block_map);
129+
block_map_clear(rv, &rv->block_map);
130+
mpool_destroy(rv->block_mp);
131+
mpool_destroy(rv->block_ir_mp);
126132
free(rv->block_map.map);
127133
free(rv);
128134
}

src/riscv.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
extern "C" {
1212
#endif
1313

14+
#define BLOCK_MAP_CAPACITY_BITS 10
15+
#define BLOCK_CAPACITY_BITS 10
16+
1417
#define RV_REGS_LIST \
1518
_(zero) /* hard-wired zero, ignoring any writes */ \
1619
_(ra) /* return address */ \

src/riscv_private.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ typedef struct {
6868
} block_map_t;
6969

7070
/* clear all block in the block map */
71-
void block_map_clear(block_map_t *map);
71+
void block_map_clear(riscv_t *rv, block_map_t *map);
7272

7373
struct riscv_internal {
7474
bool halt; /* indicate whether the core is halted */
@@ -121,7 +121,7 @@ struct riscv_internal {
121121

122122
bool compressed; /**< current instruction is compressed or not */
123123
block_map_t block_map; /**< basic block map */
124-
124+
struct mpool *block_mp, *block_ir_mp;
125125
/* print exit code on syscall_exit */
126126
bool output_exit_code;
127127
};

0 commit comments

Comments
 (0)