-
-
Notifications
You must be signed in to change notification settings - Fork 184
Basic API
This page contains description of basic easy_profiler API.
Enumeration type to control profiled blocks on/off statuses. This is optional feature (all blocks are ON
by default).
You can always change status of a block at run-time with GUI client, you don't need to change your source code.
Possible values:
-
OFF
= The block is OFF (block will not be profiled, but it's children would). -
ON
= The block is ON (but if it's parent block is off recursively then this block will be off too). -
FORCE_ON
= The block is ALWAYS ON (even if it's parent has turned off all children). -
OFF_RECURSIVE
= The block is OFF and all of it's children (by call-stack) are also OFF. -
ON_WITHOUT_CHILDREN
= The block is ON but all of it's children are OFF. -
FORCE_ON_WITHOUT_CHILDREN
= The block is ALWAYS ON but all of it's children are OFF.
Enumeration type used for convertion of FPS value (see Getting FPS)
Possible values:
-
TICKS
= FPS value in CPU ticks -
MICROSECONDS
= FPS value in microseconds
Use these macros to enable/disable profiling. Profiling information stored only when profiler is enabled. EasyProfiler is disabled by default. Using these macros is optional because you can always start/stop profiling session via EasyProfiler GUI.
Instead of enabling/disabling profiler manually you can do this via remote GUI.
In the profiled application you need to put profiler::startListen()
or profiler::startListen(<port number>)
to start listening network commands from GUI.
In GUI you need to connect to the profiled application using IP-address (or computer name) and port number passed to startListen()
function.
Default port number is 28077
.
Ends last opened block. If last block is OFF
then do nothing.
Opens new profiler block. The block will be ended on it's destructor when closing brace will be met or it can be ended manually using EASY_END_BLOCK
macro.
It's 1st parameter is block name. It accepts C-strings and std::string. Compile-time strings are inserted into block description (only once per application launch) and not included into every profiled block. Run-time strings are serialized together with every profiled block, so it is much more efficient to use compile-time strings if block name does not change at run-time.
Rest two optional parameters are (their order is not strict):
- block color in 32-bit ARGB integer format (you can use one of predefined colors from
profiler::colors
namespace or create your own custom color); - block activity status (see
enum EasyBlockStatus
). All block statuses could be changed dynamically at run-time from EasyProfiler GUI. Default status isprofiler::ON
Example:
#include <easy/profiler.h>
void foo(const char* loopName) {
EASY_BLOCK("Red block", profiler::colors::Red); // A
// some code
EASY_END_BLOCK; // A end
EASY_BLOCK(loopName, profiler::ON_WITHOUT_CHILDREN, profiler::colors::Amber700); // B
for (int i = 0; i < 100; ++i) {
EASY_BLOCK("Loop body"); // This block is disabled by parent activity status and will not be profiled
// some code
}
EASY_BLOCK("Child", profiler::FORCE_ON); // C . This block will be profiled forcedly.
// some another code
EASY_END_BLOCK; // C end. This will never affect block B even if C status will be profiler::OFF.
EASY_END_BLOCK; // This always refer to block B even if it's status will be profiler::OFF
// some code
}
This is just syntactic sugar for EASY_BLOCK(__FUNCTION__, ...);
(for Windows) or EASY_BLOCK(__func__, ...);
(for Linux).
Example:
#include <easy/profiler.h>
int bar() {
EASY_FUNCTION(); // Block with name "bar" and default color
// some code
return 0;
}
Insert user defined mark into profiler timeline. This is same as EASY_BLOCK
except such blocks has no duration (ends immidiately).
Also, event markers are displayed on timeline under the blocks.
Example:
#include <easy/profiler.h>
bool ResourceManager::load() {
EASY_FUNCTION(profiler::colors::Yellow500);
// some code...
EASY_EVENT("Resources loaded", profiler::colors::Magenta);
return true;
}
Set name for current thread. Also creates scoped ThreadGuard
object which marks current thread as expired and creates ThreadFinished
event on it's destructor.
Notice: Please, insert this macro into the main thread function (which returns only on thread finish) or some errors may occur.
Only first invoke of the macro has an effect (setting a name). Using this macro is optional but without it you will see raw thread id in profiler timeline instead of human readable name.
Example:
#include <easy/profiler.h>
void workerThread(void* parameters) {
EASY_THREAD_SCOPE("Worker"); // Setting name for current thread from a main worker function
while (true) {
EASY_BLOCK("Worker step");
// main worker cycle
}
}
int main() {
int dummy1 = 1, dummy2 = 2;
EASY_PROFILER_ENABLE;
std::thread t1(workerThread, &dummy1);
std::thread t2(workerThread, &dummy2);
t1.join();
t2.join();
return 0;
}
Set name for current thread.
Notice: This macro does not create a ThreadGuard
and can be invoked from every function you want, but there is no ThreadFinished
event.
Only first invoke of the macro has an effect (setting a name). Using this macro is optional but without it you will see raw thread id in profiler timeline instead of human readable name.
Example:
#include <easy/profiler.h>
void foo() {
EASY_FUNCTION();
// ...
}
void bar() {
EASY_THREAD("Worker"); // Setting name for current thread from a custom worker function
// which may be invoked multiple times
EASY_FUNCTION();
// ...
}
void workerThread(void* parameters) {
while (true) {
EASY_BLOCK("Worker step");
// main worker cycle
foo();
bar(); // Only first invoke will give this thread a name
bar();
bar();
}
}
int main() {
int dummy1 = 1, dummy2 = 2;
EASY_PROFILER_ENABLE;
std::thread t1(workerThread, &dummy1);
std::thread t2(workerThread, &dummy2);
t1.join();
t2.join();
return 0;
}
This is syntactic sugar for EASY_THREAD("Main")
.
Note: EasyProfiler does not force you to mark main thread except the case if you want to get an FPS value.
Example:
#include <easy/profiler.h>
int main() {
EASY_MAIN_THREAD;
EASY_PROFILER_ENABLE;
while (true) {
// main application cycle
}
return 0;
}
EasyProfiler calculates FPS value continually even if profiler is disabled. This is done to let you inspect your application frame rate and to let you enable profiler in proper time. EasyProfiler GUI has FPS Monitor widget so, in most cases, you do not need to use API functions directly to get FPS value. But if you want to, you can use API functions described below. Note: "Frame" means every top-level block (which has no parent).
To get main thread FPS you have to mark main thread first. Use EASY_MAIN_THREAD
macro for that purpose.
After that you can get FPS values using profiler::main_thread_frameTime...
bunch of functions or profiler::main_thread::
namespace.
profiler::main_thread_frameTime()
returns last frame duration.
profiler::main_thread_frameTimeLocalMax()
returns frame local max duration which is max duration since last call of the function.
profiler::main_thread_frameTimeLocalAvg()
same as local max, but returns local average duration.
All functions have one optional argument Duration _durationCast
which could be used to convert result to CPU-ticks or microseconds.
All functions have prototypes in profiler::main_thread::
namespace. For example, profiler::main_thread::frameTimeLocalMax()
.
This is almost the same like main thread functions, but used for current active thread.
Use profiler::this_thread_...
functions or profiler::this_thread::
namespace.