From 8c477e9667f088a288da43ca07e1daee6767b745 Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Sat, 24 Aug 2024 16:37:18 +0200 Subject: [PATCH] Adding gprof custom example --- src/samples/Makefile.am | 1 + src/samples/Makefile.samples | 1 + src/samples/gprof/custom/Makefile.sample | 16 +++++ src/samples/gprof/custom/README.md | 57 +++++++++++++++++ src/samples/gprof/custom/main.c | 78 ++++++++++++++++++++++++ 5 files changed, 153 insertions(+) create mode 100644 src/samples/gprof/custom/Makefile.sample create mode 100644 src/samples/gprof/custom/README.md create mode 100644 src/samples/gprof/custom/main.c diff --git a/src/samples/Makefile.am b/src/samples/Makefile.am index 9868d6ef..2db7137b 100644 --- a/src/samples/Makefile.am +++ b/src/samples/Makefile.am @@ -13,6 +13,7 @@ SAMPLES = \ debug/sio \ debug/gdb \ gprof/basic \ + gprof/custom \ gu/beginobject \ gu/blend \ gu/blit \ diff --git a/src/samples/Makefile.samples b/src/samples/Makefile.samples index 8de3c611..e8c88ffc 100644 --- a/src/samples/Makefile.samples +++ b/src/samples/Makefile.samples @@ -10,6 +10,7 @@ SAMPLES = \ debug/sio \ debug/gdb \ gprof/basic \ + gprof/custom \ gu/beginobject \ gu/blend \ gu/blit \ diff --git a/src/samples/gprof/custom/Makefile.sample b/src/samples/gprof/custom/Makefile.sample new file mode 100644 index 00000000..3338be0c --- /dev/null +++ b/src/samples/gprof/custom/Makefile.sample @@ -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 diff --git a/src/samples/gprof/custom/README.md b/src/samples/gprof/custom/README.md new file mode 100644 index 00000000..16aaa5a6 --- /dev/null +++ b/src/samples/gprof/custom/README.md @@ -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 + +[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. \ No newline at end of file diff --git a/src/samples/gprof/custom/main.c b/src/samples/gprof/custom/main.c new file mode 100644 index 00000000..7bd73799 --- /dev/null +++ b/src/samples/gprof/custom/main.c @@ -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 +#include +#include +#include +#include + +#include +#include +#include + +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; +} \ No newline at end of file