mirror of
https://github.com/ringtailsoftware/uvm32.git
synced 2026-06-05 22:43:39 +00:00
Add a simple statistical profiler
Some checks are pending
CI / test (ubuntu-latest) (push) Waiting to run
Some checks are pending
CI / test (ubuntu-latest) (push) Waiting to run
Enabled by -p, will sample program counter and store frequency. Using "-i 1" will make execution pause on every instruction and sample PC.
host-sdl -p -i 1 foo.bin | grep times > log.txt
cat log.txt | sort -n -k4
Can match addresses with
riscv64-elf-objdump -S -d -f foo.bin
This commit is contained in:
parent
6a6d7f1832
commit
53b5eeb256
1 changed files with 43 additions and 1 deletions
|
|
@ -22,6 +22,8 @@ int HEIGHT = 200;
|
|||
#define WINDOW_WIDTH WIDTH*3
|
||||
#define WINDOW_HEIGHT HEIGHT*3
|
||||
|
||||
static uint32_t *profiling_data = NULL;
|
||||
|
||||
// circular buffer of keypresses, so vm code can read them as it's ready
|
||||
typedef struct {
|
||||
bool down;
|
||||
|
|
@ -39,6 +41,29 @@ static int16_t audioBuffer[AUDIOBUFFER_LEN];
|
|||
static int audioBufferWr = 0;
|
||||
static int audioBufferRd = 0;
|
||||
|
||||
void profiling_init(uvm32_state_t *vmst) {
|
||||
profiling_data = malloc(sizeof(uint32_t) * UVM32_MEMORY_SIZE);
|
||||
memset(profiling_data, 0x00, sizeof(uint32_t) * UVM32_MEMORY_SIZE);
|
||||
}
|
||||
|
||||
void profiling_update(uvm32_state_t *vmst) {
|
||||
uint32_t pc_rel = uvm32_getProgramCounter(vmst) - 0x80000000;
|
||||
if (pc_rel > UVM32_MEMORY_SIZE) {
|
||||
// don't handle PC being in extram
|
||||
printf("pc > memory size! %08x\n", pc_rel);
|
||||
} else {
|
||||
profiling_data[pc_rel] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
void profiling_dump(void) {
|
||||
for (int i=0;i<UVM32_MEMORY_SIZE;i++) {
|
||||
if (profiling_data[i] > 0) {
|
||||
printf("Addr %08x hit %d times\n", 0x80000000 + i, profiling_data[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void key_enq(uint16_t scancode, bool down) {
|
||||
keyBuffer[keyBufferWr].scancode = scancode;
|
||||
keyBuffer[keyBufferWr].down = down;
|
||||
|
|
@ -126,6 +151,7 @@ void usage(const char *name) {
|
|||
printf(" -h show help\n");
|
||||
printf(" -i <num instructions> max instrs before requiring a syscall\n");
|
||||
printf(" -e <extram size> numbers of bytes for extram\n");
|
||||
printf(" -p enable profiling\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
@ -168,6 +194,7 @@ int main(int argc, char *argv[]) {
|
|||
SDL_Window *screen = NULL;
|
||||
SDL_Event event;
|
||||
SDL_Texture *render_target = NULL;
|
||||
bool use_profiling = false;
|
||||
|
||||
// memory for vmst is very large, so allocate
|
||||
vmst = (uvm32_state_t *)malloc(sizeof(uvm32_state_t));
|
||||
|
|
@ -177,7 +204,7 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
// parse commandline args
|
||||
while ((c = getopt(argc, argv, "hi:e:W:H:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "hi:e:W:H:p")) != -1) {
|
||||
switch(c) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
|
|
@ -197,6 +224,9 @@ int main(int argc, char *argv[]) {
|
|||
case 'H':
|
||||
HEIGHT = strtoll(optarg, NULL, 10);
|
||||
break;
|
||||
case 'p':
|
||||
use_profiling = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (optind < argc) {
|
||||
|
|
@ -261,6 +291,10 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
SDL_ResumeAudioStreamDevice(stream);
|
||||
|
||||
if (use_profiling) {
|
||||
profiling_init(vmst);
|
||||
}
|
||||
|
||||
while (isrunning) {
|
||||
SDL_PollEvent(&event);
|
||||
|
||||
|
|
@ -280,6 +314,10 @@ int main(int argc, char *argv[]) {
|
|||
break;
|
||||
}
|
||||
|
||||
if (use_profiling) {
|
||||
profiling_update(vmst);
|
||||
}
|
||||
|
||||
total_instrs += uvm32_run(vmst, &evt, max_instrs_per_run); // num instructions before vm considered hung
|
||||
num_syscalls++;
|
||||
|
||||
|
|
@ -396,6 +434,10 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
printf("Executed total of %lu instructions and %lu syscalls\n", (unsigned long)total_instrs, (unsigned long)num_syscalls);
|
||||
|
||||
if (use_profiling) {
|
||||
profiling_dump();
|
||||
}
|
||||
|
||||
free(rom);
|
||||
if (extram_buf != NULL) {
|
||||
free(extram_buf);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue