Adding gprof custom example

This commit is contained in:
Francisco Javier Trujillo Mata
2024-08-24 16:37:18 +02:00
parent 72c5c4ab25
commit 8c477e9667
5 changed files with 153 additions and 0 deletions

View File

@@ -13,6 +13,7 @@ SAMPLES = \
debug/sio \
debug/gdb \
gprof/basic \
gprof/custom \
gu/beginobject \
gu/blend \
gu/blit \

View File

@@ -10,6 +10,7 @@ SAMPLES = \
debug/sio \
debug/gdb \
gprof/basic \
gprof/custom \
gu/beginobject \
gu/blend \
gu/blit \

View File

@@ -0,0 +1,16 @@
TARGET = gprofcustom
OBJS = main.o
INCDIR =
CFLAGS = -O2 -Wall -pg -g
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
LIBDIR =
LDFLAGS = -pg -g
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = GProf Custom Example
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak

View File

@@ -0,0 +1,57 @@
More advance example about how to use the `gprof` feature.
The requiremnts are quite easy, just adding `-g -pg` flags to the `CFLAGS` and `LDFLAGS` is enough to make things to work out of the box.
This example shows how to enable profiling just around some specific piece of code.
How `gprof` by default start profiling from the very beginning of the app we must discard that result, this is why we do `gprof_stop(NULL, false);`.
Then we just need to call `gprof_start();` whenever we want to start meassuring our piece of code and `gprof_stop("gmon_custom.out", true);` whenver we want to stop the profiling.
Firstly execute your program, then once program ends it will automatically generates the output with the given names.
In order to inspect the content of the generated file you need to use the `psp-gprof` binary.
For instance, following the next syntax:
```
psp-gprof -b {binary.elf} {gmon_custom.out}
```
like:
```
psp-gprof -b gprofcustom.elf gmon_custom.out
```
Output in this example:
```
Flat profile:
Each sample counts as 0.001 seconds.
% cumulative self self total
time seconds seconds calls s/call s/call name
89.78 5.60 5.60 1 5.60 5.60 heavy_operation_3
10.22 6.24 0.64 1 0.64 0.64 heavy_operation_2
Call graph
granularity: each sample hit covers 2 byte(s) for 0.02% of 6.24 seconds
index % time self children called name
<spontaneous>
[1] 100.0 0.00 6.24 main [1]
5.60 0.00 1/1 heavy_operation_3 [2]
0.64 0.00 1/1 heavy_operation_2 [3]
-----------------------------------------------
5.60 0.00 1/1 main [1]
[2] 89.8 5.60 0.00 1 heavy_operation_3 [2]
-----------------------------------------------
0.64 0.00 1/1 main [1]
[3] 10.2 0.64 0.00 1 heavy_operation_2 [3]
-----------------------------------------------
Index by function name
[3] heavy_operation_2 [2] heavy_operation_3
```
Cheers.

View File

@@ -0,0 +1,78 @@
/*
* PSP Software Development Kit - https://github.com/pspdev
* -----------------------------------------------------------------------
* Licensed under the BSD license, see LICENSE in PSPSDK root for details.
*
* main.c - A more advadced example for checking the GProf profiler.
* This example demonstrates how to start and stop the profiler multiple times
*
* Copyright (c) 2024 Francisco Javier Trujillo Mata - fjtrujy@gmail.com
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>
#include <unistd.h>
#include <pspmoduleinfo.h>
#include <pspthreadman.h>
#include <pspprof.h>
PSP_MODULE_INFO("GProf Custom Example", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);
// Simulates a CPU-bound heavy operation by calculating large numbers of square roots
void heavy_operation_1() {
double result = 0.0;
for (long i = 1; i < 100000; i++) {
result += sqrt((double)i);
}
printf("Result of heavy_operation_1: %f\n", result);
}
// Simulates a different CPU-bound heavy operation by calculating factorials
void heavy_operation_2() {
unsigned long long result = 1;
for (int i = 1; i < 20; i++) {
result = 1;
for (int j = 1; j <= i * 10000; j++) {
result *= j;
result %= 100000; // Prevent overflow by keeping the result manageable
}
}
printf("Result of heavy_operation_2: %llu\n", result);
}
// Simulates a mixed heavy operation (CPU + IO-bound) by performing some calculations and sleeping
void heavy_operation_3() {
double result = 1.0;
for (long i = 1; i < 50000; i++) {
result *= log((double)i);
if (i % 10000 == 0) {
printf("Heavy operation 3, part %ld: sleeping for 1 second...\n", i / 1000000);
sleep(1); // Simulate some IO-bound activity
}
}
printf("Result of heavy_operation_3: %f\n", result);
}
int main() {
// Initial heavy operation (this part will be ignored in profiling)
heavy_operation_1();
// Stop profiling (ignore the above operation in gprof output)
gprof_stop(NULL, false);
// Start profiling again
gprof_start();
// Operations to be profiled
heavy_operation_2();
heavy_operation_3();
// Stop profiling and save the output to a custom file
gprof_stop("gmon_custom.out", true);
return 0;
}