Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic profiler. #20238

Merged
merged 8 commits into from
Apr 5, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions quantum/basic_profiling.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright 2023 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once

/*
This API allows for basic profiling information to be printed out over console.

Usage example:

#include "basic_profiling.h"

// Original code:
matrix_task();

// Delete the original, replace with the following (variant 1, automatic naming):
PROFILE_CALL(1000, matrix_task());

// Delete the original, replace with the following (variant 2, explicit naming):
PROFILE_CALL_NAMED(1000, "matrix_task", {
matrix_task();
});
*/

#if defined(PROTOCOL_LUFA) || defined(PROTOCOL_VUSB)
# define TIMESTAMP_GETTER TCNT0
#elif defined(PROTOCOL_CHIBIOS)
# define TIMESTAMP_GETTER chSysGetRealtimeCounterX()
#elif defined(PROTOCOL_ARM_ATSAM)
# error arm_atsam not currently supported
#else
# error Unknown protocol in use
#endif

#ifndef CONSOLE_ENABLE
// Can't do anything if we don't have console output enabled.
# define PROFILE_CALL_NAMED(count, name, call) \
do { \
} while (0)
#else
# define PROFILE_CALL_NAMED(count, name, call) \
do { \
static uint64_t inner_sum = 0; \
static uint64_t outer_sum = 0; \
uint32_t start_ts; \
static uint32_t end_ts; \
static uint32_t write_location = 0; \
start_ts = TIMESTAMP_GETTER; \
if (write_location > 0) { \
outer_sum += start_ts - end_ts; \
} \
do { \
call; \
} while (0); \
end_ts = TIMESTAMP_GETTER; \
inner_sum += end_ts - start_ts; \
++write_location; \
if (write_location >= ((uint32_t)count)) { \
uint32_t inner_avg = inner_sum / (((uint32_t)count) - 1); \
uint32_t outer_avg = outer_sum / (((uint32_t)count) - 1); \
dprintf("%s -- Percentage time spent: %d%%\n", (name), (int)(inner_avg * 100 / (inner_avg + outer_avg))); \
tzarc marked this conversation as resolved.
Show resolved Hide resolved
inner_sum = 0; \
outer_sum = 0; \
write_location = 0; \
} \
} while (0)

#endif // CONSOLE_ENABLE

#define PROFILE_CALL(count, call) PROFILE_CALL_NAMED(count, #call, call)