Skip to content

Instantly share code, notes, and snippets.

@xerpi
Created August 5, 2016 13:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xerpi/faacf7d3af84325a50635249da79406d to your computer and use it in GitHub Desktop.
Save xerpi/faacf7d3af84325a50635249da79406d to your computer and use it in GitHub Desktop.
Vita static profiling
#include <cstdio>
#include <cstdint>
#include <cstdlib>
#include <cinttypes>
#include <map>
struct prof_log_entry {
uint64_t time;
uint64_t calls;
char name[64];
} __attribute__((packed));
int main(int argc, char *argv[])
{
size_t i, j;
FILE *fp;
size_t size;
void *buffer;
prof_log_entry *entry;
size_t num_entries;
uint64_t total_time;
if (argc < 2)
goto error_exit;
fp = fopen(argv[1], "rb");
if (!fp) {
printf("Error opening \'%s\'\n", argv[1]);
goto error_exit;
}
fseek(fp, 0, SEEK_END);
size = ftell(fp);
rewind(fp);
buffer = malloc(size);
if (!buffer) {
printf("Error allocating %ld bytes.\n", size);
goto error_malloc;
}
if (fread(buffer, 1, size, fp) != size) {
printf("Error reading %ld bytes from the file.\n", size);
goto error_read;
}
num_entries = 0;
total_time = 0;
entry = (struct prof_log_entry *)buffer;
for (; (uintptr_t)entry < (uintptr_t)buffer + size; entry++) {
total_time += entry->time;
num_entries++;
for (j = 1; j < 64; j++) {
if (entry->name[j] == '(') {
entry->name[j] = '\0';
break;
}
}
}
printf("Total time: %" PRIu64 "us\n", total_time);
if (total_time > 0) {
entry = (struct prof_log_entry *)buffer;
for (i = 0; i < num_entries; i++) {
printf("%9.6f%% - %8" PRIu64 "us - %8" PRIu64 " call(s) - %s\n",
((double)entry[i].time / total_time) * 100,
entry[i].time,
entry[i].calls,
entry[i].name);
}
}
free(buffer);
fclose(fp);
return 0;
error_read:
free(buffer);
error_malloc:
fclose(fp);
error_exit:
return -1;
}
#include <string.h>
#include <psp2/io/fcntl.h>
#include "profiling.h"
struct prof_log_entry {
uint64_t time;
uint64_t calls;
const char *name;
} __attribute__((packed));
#define PROG_LOG_SIZE (128)
static struct prof_log_entry log_entries[PROG_LOG_SIZE];
static unsigned int log_entries_size = 0;
static SceUID fd = -1;
SceKernelSysClock prof_start_time;
SceKernelSysClock prof_end_time;
const char *prof_func_name;
void prof_init(const char *filename)
{
fd = sceIoOpen(filename, SCE_O_WRONLY | SCE_O_CREAT | SCE_O_TRUNC, 0777);
if (fd < 0) {
return;
}
log_entries_size = 0;
}
void prof_finish()
{
int i;
char func_name[64];
struct prof_log_entry *entry;
if (fd < 0)
return;
entry = log_entries;
for (i = 0; i < log_entries_size; i++, entry++) {
sceIoWrite(fd, entry, sizeof(entry->time) + sizeof(entry->calls));
strncpy(func_name, entry->name, 64);
sceIoWrite(fd, func_name, sizeof(func_name));
}
sceIoClose(fd);
fd = -1;
}
void prof_log(const SceKernelSysClock *start, const SceKernelSysClock *end, const char *name)
{
int i;
int found = 0;
for (i = 0; i < log_entries_size && !found; i++) {
if (log_entries[i].name == name) {
found = 1;
break;
}
}
if (!found) {
i = log_entries_size;
log_entries[i].name = name;
log_entries[i].calls = 0;
log_entries_size++;
}
log_entries[i].time += *end - *start;
log_entries[i].calls++;
}
#ifndef PROFILING_H
#define PROFILING_H
#include <psp2/types.h>
#include <psp2/kernel/processmgr.h>
#ifdef __cplusplus
extern "C" {
#endif
void prof_init(const char *filename);
void prof_finish();
void prof_log(const SceKernelSysClock *start, const SceKernelSysClock *end, const char *name);
extern SceKernelSysClock prof_start_time;
extern SceKernelSysClock prof_end_time;
extern const char *prof_func_name;
#define PROF_INIT(name) \
{ \
prof_func_name = (name); \
sceKernelGetProcessTime(&prof_start_time); \
}
#define PROF_END() \
{ \
sceKernelGetProcessTime(&prof_end_time); \
prof_log(&prof_start_time, &prof_end_time, prof_func_name); \
}
#define PROF(func) \
{ \
SceKernelSysClock start; \
SceKernelSysClock end; \
sceKernelGetProcessTime(&start); \
func; \
sceKernelGetProcessTime(&end); \
prof_log(&start, &end, # func); \
}
#define PROF_RET(func) \
({ \
typeof(func) ret; \
SceKernelSysClock start; \
SceKernelSysClock end; \
sceKernelGetProcessTime(&start); \
ret = func; \
sceKernelGetProcessTime(&end); \
prof_log(&start, &end, # func); \
ret; \
})
#ifdef __cplusplus
}
#endif
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment