microprofile is an embeddable profiler

Related tags

Debug microprofile
Overview

Build Status

microprofile

Microprofile is a embeddable profiler in a few files, written in C++ Microprofile is hosted on

Integration

#include "microprofile.h"
{
	MICROPROFILE_SCOPEI("group","timername", MP_YELLOW);
	... code to be timed
}

And once each frame you should call

MicroProfileFlip(nullptr);

The implementation of microprofile is in microprofile.cpp, which you must include in your project.

The nullpointer is the void* device context passed for gpu timers.

MicroProfile can be used without calling MicroProfileFlip, in which case you should call MicroProfileDumpFileImmediately, to save the profile data as .html/.csv file on disk.

Gpu Timing

Gpu timers work like normal timers, except they are all put in a shared group, "GPU". To use them insert MICROPROFILE_SCOPEGPUI(). Gpu timers also supports multithreaded renderers - Please refer to demo_nouid3d12 for an example of how to use this. Gpu timers are available for the following apis:

  • OpenGL
  • D3D11
  • D3D12
  • Vulkan

Counters

MicroProfile has support for tracking various counters, that will then be shown in the live & capture views.

	MICROPROFILE_COUNTER_ADD("memory/main", 1000);
	MICROPROFILE_COUNTER_SET("fisk/geder/", 42);

Timeline

The Timeline view in a capture is intended to mark longer, unique timers. It can be used to show stuff like a level loading, with the levels name included.

  • They are intended to mark state that last a long timer - Longer than a single frame
  • They do not appear in the aggregation and cannot be viewed from the
  • They are always active, and are all considered unique
  • They can have fancy names with custom formatted strings.

There are two ways to use it. The first one uses unformatted static string literals:

	MICROPROFILE_TIMELINE_ENTER_STATIC(MP_DARKGOLDENROD, "one");
	MICROPROFILE_TIMELINE_LEAVE_STATIC("one");

The second option allows for arbitrary strings, but requires a token is stored, for the profiler to identify when leaving the marker:

	MICROPROFILE_TIMELINE_TOKEN(token);
	MICROPROFILE_TIMELINE_ENTERF(token, MP_YELLOW, "custom %d %6.2f", 10, 42.0f);
	MICROPROFILE_TIMELINE_LEAVE(token);

Live View

To start microprofile in live mode, simply point chrome to host:1338/ The live view can be used to enable different microprofile groups, using the Control menu. If no groups are enabled, no code is timed. Press the capture button to generate a capture. By default the last 30 frames are capture. The capture itself is a fully contained webpage, that can be saved and shared for further reference.

There are a few ways the webserver can be invoked

  • host:1338/100 (capture 100 frames)
  • host:1338/p/foo (start live view, load preset foo)
  • host:1338/b/foo (start live view, load builtin preset foo)

Presets can be loaded and saved directly from the webbrowser. They are saved by the application in a file named mppresets.cfg. builtin presets are presets, that are loaded from mppresets.builtin.cfg. They work like presets, except they only be loaded. This is intended to be used to do predefined, non-overwriteable configurations.

Alt text

Capture view

Capturing in live view provides a complete view of what is recorded in the ring buffers over a set amount of frames. Please be aware if you capture to far behind, the markers you're are looking for might be overwritten, in which case there will be no markers. As the buffers are reused per thread, this is something that will happen on a per thread basis.

Alt text

Comparing captures

Microprofile supports comparing two different captures. Save the first capture to disk, open the second capture and click compare and browse to the first file. Please be aware that:

  • Only the detailed view is supported
  • Captures saved from earlier versions will not work with this feature
  • When context switch trace is enabled, comparing will only compare registered threads.

Dynamic Instrumentation

On Intel x86-64 Microprofile supports dynamically injecting markers into running code. This is supported on windows, osx and linux(tested on ubuntu) To use this feature

  • Make sure MICROPROFILE_DYNAMIC_INSTRUMENT_ENABLE is defined
  • Make sure to link with distorm and add its include folder to the include path
  • Check dynamic_instrument for an example
  • hold down alt to pan the secondary capture without moving the first capture

Please be aware that this is still a bit experimental, and be aware of these limitations:

  • The profiler does not attempt to stop all running threads while instrumenting.
    • This potentially can cause issues, as there is a critical moment when replacing the first 14 bytes of the function being patched. If any thread is executing the code begin replaced, the program behaviour will not be well defined
    • For development this is usually fine
  • The instrumentation does not need the program to be compiled or linked in any specific way
    • But it does not support instrumenting all possible x86-64 code sequences - IE it might fail.
    • It needs at least 14 bytes of instructions to instrument a function
  • On linux you need to link your program with -rdynamic, in order to make the it possible to find the functions using dladdr
    • if you know of any way to query this without linking with -rdynamic I'd love to hear about it.

If compiled and linked with Dynamic Instrumentation, two new menus appear, "modules" and "functions".

The "modules" menu allows you to load debug information from your loaded modules. Select one or more modules to load from. Once its loaded the bar behind the module name is filled, and the debug information is ready.

Modules screenshot

Once the debug symbols are loaded - Indicated by the number in the top of the functions menu - You can start typing to search for functions to instrument.

  • Click on a function to attempt to instrument it
  • If instrumentation fails, you´ll be asked to report the code sequence. Please consider doing this.
  • Click on '>>' next to a function, to attempt to instrument all the functions called by that function
    • Only functions called that also have a name in the debug information will be instrumented

Functions screenshot

Example code

  • noframes: Using microprofile to profile an application without any concept of frames. dumps a capture at the end. No live view.
  • simple: frame based implementation. with live view. No gpu timing
  • d3d11: frame based implementation, with live view and D3D11 gpu timers
  • d3d12: frame based implementation, with live view and D3D12 gpu timers
  • d3d12_multithreading: frame based implementation, with live view and D3D12 gpu timers, with gpu timings generated from multiple threads.
  • gl: frame based implementation, with live view and OpenGL gpu timers
  • vulkan: Copy of the vulkan Hologram sample, fixed to use microprofile cpu and gpu markers. Only tested on windows.
  • dynamic_instrument: Demo for dynamic instrumentation.
  • workbench: Workbench for development. Using all features of microprofile.

Dependencies

  • Microprofile supports generating compressed captures using miniz(http:/code.google.com/miniz).
  • Distorm is used to disassemble x86-64 when using dynamic instrumentation(https://github.com/gdabah/distorm)

Resource usage

MicroProfile uses a few large allocations.

  • One global instance of struct MicroProfile
  • One Large Allocation per thread that its tracking (MICROPROFILE_PER_THREAD_BUFFER_SIZE, default 2mb)
  • One Large Allocation per gpu buffer used (MICROPROFILE_PER_THREAD_GPU_BUFFER_SIZE, default 128k)
  • one thread for sending
  • one thread for handling context switches, when enabled
  • 128kb for context switch data, when context switch tracing is enabled.
  • two small variable size buffers. should not be more than a few kb.
    • A state buffer for receiving websocket packets
    • A state buffer for loading/saving settings.
  • one small allocation for receiving packets from the sender

To change how microprofile allocates memory, define these macros when compiling microprofile implementation

  • MICROPROFILE_ALLOC
  • MICROPROFILE_REALLOC
  • MICROPROFILE_FREE

microprofile.config.h

Microprofile has lots of predefined macros that can be changed. To modify this, make sure MICROPROFILE_USE_CONFIG is defined, and put the changed defines in microprofile.config.h.

Known Issues & Limitations

There are a few minor known issues & Limitations:

  • Currently the relative placement of gpu timings vs the cpu timings tend to slide a bit, and thus the relative position of GPU timestamps and CPU timestamp are not correct.
  • Chrome has an internal limit to how big a page it will cache. if you generate a capture file that is larger than 32mb, chrome will refuse to cache it. This causes the page to redownload when you save it, which is pretty catastrophic, since it will generate a capture. To mitigate this:
    • Use miniz. This drastically reduces the size of captures, to the point where its no longer a problem
    • If you still have issues, increase chromes disk cache size.
  • If you're dynamically creating threads, you must call MicroProfileOnThreadExit when threads exit, to reuse the thread log objects

Console support

Microprofile supports the two major consoles - Search for 'microprofile' in the closed platform forums.

License

Licensed using unlicense.org

Comments
  • How do I customize microprofile metrics URL

    How do I customize microprofile metrics URL

    It is a basic question but I am unable to find information on this.

    Unlike Spring Actuator, which adds context path to the URL automatically, I dont see this happening with Microprofile. So, I end up with say /metrics url like

    https://myserver/metrics

    This however is not good enough. I would like to have url like:

    https://myserver/myApi/metrics

    , where myApi is the context path of myApi application.

    Otherwise, if I have 10 application all exposing metrics data on same url (https://myserver/metrics), it is difficult to distinguish between them.

    opened by dbnex14 8
  • Fix build on BSDs

    Fix build on BSDs

    Assume POSIX is the fallback. Anything that deviates from it can #ifdef like Windows or OS X. This is a rebased version of https://bitbucket.org/jonasmeyer/microprofile/pull-requests/10/

    opened by jbeich 8
  • OpenGL profiling?

    OpenGL profiling?

    Is OpenGL profiling deprecated? I cannot find a demo that does this.

    Tried to build microprofile with -DMICROPROFILE_GPU_TIMERS=1 -DMICROPROFILE_GPU_TIMERS_GL=1 on OS X. After adding the missing gl headers to microprofile.cpp the build fails with a linker error that no _MicroProfileGpuFlip and _MicroProfileGpuShutdown are found.

    Any help would be appreciated.

    opened by gaborpapp 7
  • Fixed live view issue with locales other than POSIX

    Fixed live view issue with locales other than POSIX

    Live view doesn't work in any browser since floating point data (stored in JSON) has been sent using current user locale with LC_NUMERIC other than POSIX format (when floating point contains delimiter other than dot and/or contains thousand delimiters). However JSON format requires POSIX floating point format.

    This fix doesn't use setlocale() as it is not thread safe. Instead it uses simple but efficient approach. This will work with most locales except exotic where decimal delimiter and thousand separator are stored in more than 1 character.

    Also this changes are safe since new functionality could be switched on/off using macro.

    opened by ans-hub 6
  • read access violation in microprofile.cpp:3828

    read access violation in microprofile.cpp:3828

    Hey,

    this project looks very useful, thanks for making it! :) I'm trying microprofile for the first time and I'm always getting a read access violation (see title) as soon as I try to capture frames using the capture button in the live view. I'm testing this with the noui_vulkan demo running with VS2015 on Windows 8.1. It doesn't crash if I go to 127.0.0.1:1338/30 directly, but it also does not display any data. I'm not sure how to actually use microprofile yet, but it looks like I can currently not get any capture data out of the demo app... Am I missing something?

    Thank you.

    opened by ands 5
  • Gpu tag naming

    Gpu tag naming

    These are a few changes I made to fix problems I was seeing in various use cases which may not be super common.

    • Added "GPU" to variable name for various scoped variables so they can be declared on the same line as others (when user code has a macro which uses multiple of these, they end up on the same source line).

    When you use for example both MICROPROFILE_SCOPE(...) and MICROPROFILE_SCOPEGPU(...) in another macro, LINE is the same value for both, so the two variables end up being named foo with the same line number. Calling the one from MICROPROFILE_SCOPEGPU(...) "fooGPU" is a kludge but it works well enough.

    • Made MICROPROFILE_STACK_MAX configurable.

    With an ifndef so it will have a default value if not set in microprofile.config.h or user code before including microprofile.h .

    • Included platform headers earlier to fix a few issues (symbols not being declared until later, causing type mismatches).

    • Made sure MicroProfileThreadIdType is the right type for all platforms.

    These are both problems I ran into on another platform compiling with clang ;)

    opened by Skylark13 4
  • Code Review for adding dynamically loaded DLL support

    Code Review for adding dynamically loaded DLL support

    This is tested and works (on my machine, Windows 64-bit, not profiling GPU), but nonetheless this pull request is primarily so you can provide feedback on the design. I tried to make my changes as non-disruptive (to the design and performance) and rewindable as possible. The result is macro-heavy and somewhat messy. I think it wouldn't be too harmful to turn the static variables into globals, and have their declarations be consolidated right at the same place as the MicroProfileGlobalState struct. Renaming static depending on its context was just for me to find the globals more quickly, so that change can be blasted if you like. The usage code could be simplified if I made it so that everything that is global is TLS. Or got rid of the TLS and used a hashtable to find logs. Again, I wanted to be non-disruptive. Sorry about the # of commits. Let me know what you think.

    opened by OswaldHurlem 4
  • Use cmake is error.

    Use cmake is error.

    When I compile the source code use cmake and c++17, I got the error

    my cmake code is

    
    INCLUDE_DIRECTORIES(
        ${PROJECT_SOURCE_DIR}/lib/microprofile
    )
    
    
    
    LINK_DIRECTORIES(
        ${PROJECT_SOURCE_DIR}/lib/microprofile
    )
    set(SOURCES
    
        ${PROJECT_SOURCE_DIR}/lib/microprofile/microprofile.cpp
        ${PROJECT_SOURCE_DIR}/main.cc
    
    
    )
    
    
    

    main code is

    
    #define MICROPROFILE_MAX_FRAME_HISTORY (2<<10)
    #define MICROPROFILE_IMPL
    #include "microprofile.h"
    
    int main(){
        MICROPROFILE_SCOPEI("my test","timername",MP_YELLOW);
        {
        print somthing();
        }
    }
    
    
    CMakeFiles/main.dir/lib/microprofile/microprofile.cpp.o: In function `MicroProfileTickToMsMultiplierGpu':
    /home/xinlnix/project/software/jichuang2021/jichuang2021/lib/microprofile/microprofile.cpp:1128: undefined reference to `MicroProfileTicksPerSecondGpu'
    CMakeFiles/main.dir/lib/microprofile/microprofile.cpp.o: In function `MicroProfileShutdown':
    /home/xinlnix/project/software/jichuang2021/jichuang2021/lib/microprofile/microprofile.cpp:1513: undefined reference to `MicroProfileGpuShutdown'
    CMakeFiles/main.dir/lib/microprofile/microprofile.cpp.o: In function `MicroProfileGpuEnterInternal':
    /home/xinlnix/project/software/jichuang2021/jichuang2021/lib/microprofile/microprofile.cpp:2645: undefined reference to `MicroProfileGpuInsertTimeStamp'
    CMakeFiles/main.dir/lib/microprofile/microprofile.cpp.o: In function `MicroProfileGpuLeaveInternal':
    /home/xinlnix/project/software/jichuang2021/jichuang2021/lib/microprofile/microprofile.cpp:2666: undefined reference to `MicroProfileGpuInsertTimeStamp'
    CMakeFiles/main.dir/lib/microprofile/microprofile.cpp.o: In function `MicroProfileFlip_CB':
    /home/xinlnix/project/software/jichuang2021/jichuang2021/lib/microprofile/microprofile.cpp:2916: undefined reference to `MicroProfileGpuFlip'
    /home/xinlnix/project/software/jichuang2021/jichuang2021/lib/microprofile/microprofile.cpp:2961: undefined reference to `MicroProfileGpuGetTimeStamp'
    /home/xinlnix/project/software/jichuang2021/jichuang2021/lib/microprofile/microprofile.cpp:2963: undefined reference to `MicroProfileTicksPerSecondGpu'
    /home/xinlnix/project/software/jichuang2021/jichuang2021/lib/microprofile/microprofile.cpp:3076: undefined reference to `MicroProfileGpuGetTimeStamp'
    CMakeFiles/main.dir/lib/microprofile/microprofile.cpp.o: In function `MicroProfileCalcAllTimers(float*, float*, float*, float*, float*, float*, float*, float*, float*, unsigned int)':
    /home/xinlnix/project/software/jichuang2021/jichuang2021/lib/microprofile/microprofile.cpp:3545: undefined reference to `MicroProfileTicksPerSecondGpu'
    CMakeFiles/main.dir/lib/microprofile/microprofile.cpp.o: In function `MicroProfileGetTime':
    /home/xinlnix/project/software/jichuang2021/jichuang2021/lib/microprofile/microprofile.cpp:3598: undefined reference to `MicroProfileTicksPerSecondGpu'
    CMakeFiles/main.dir/lib/microprofile/microprofile.cpp.o: In function `MicroProfileDumpCsv(void (*)(void*, unsigned long, char const*), void*)':
    /home/xinlnix/project/software/jichuang2021/jichuang2021/lib/microprofile/microprofile.cpp:3958: undefined reference to `MicroProfileTicksPerSecondGpu'
    CMakeFiles/main.dir/lib/microprofile/microprofile.cpp.o: In function `MicroProfileDumpHtml(void (*)(void*, unsigned long, char const*), void*, unsigned long, char const*, unsigned long)':
    /home/xinlnix/project/software/jichuang2021/jichuang2021/lib/microprofile/microprofile.cpp:4087: undefined reference to `MicroProfileTicksPerSecondGpu'
    /home/xinlnix/project/software/jichuang2021/jichuang2021/lib/microprofile/microprofile.cpp:4393: undefined reference to `MicroProfileTicksPerSecondGpu'
    /home/xinlnix/project/software/jichuang2021/jichuang2021/lib/microprofile/microprofile.cpp:4395: undefined reference to `MicroProfileGetGpuTickReference'
    CMakeFiles/main.dir/lib/microprofile/microprofile.cpp.o: In function `MicroProfileWebSocketSendFrame(int)':
    /home/xinlnix/project/software/jichuang2021/jichuang2021/lib/microprofile/microprofile.cpp:6622: undefined reference to `MicroProfileTicksPerSecondGpu'
    collect2: error: ld returned 1 exit status
    
    
    opened by xinlnix 3
  • Is there any known limitation in frame history length?

    Is there any known limitation in frame history length?

    I increased MICROPROFILE_MAX_FRAME_HISTORY to 50000 to be able to create longer recordings (few minutes).

    • When I try to capture 1000 frames using http://127.0.0.1:1338/1000 it loads fine and I am able to save such recording. It is then approximately 155MB large.
    • When I try to capture 2000 frames it also loads fine however Chrome fails when I am trying to save it
    • When I try to capture 5000 frames the page is not even loaded

    I even tried using MICROPROFILE_MINIZ and there was no visible effect. Is there any known limitation in frame history length or capture size?

    opened by andreas-stefanidis-bisimulations 3
  • Fix OpenGL GPU profiling + use _aligned_free on Windows

    Fix OpenGL GPU profiling + use _aligned_free on Windows

    As discussed in Issue #8 , OpenGL profiling was broken due to two functions being left unimplemented.

    As I said in my reply in that issue, I'm not sure the implementations I've given are complete, only that they work for me.

    I've also included another change -- since MICROPROFILE_ALLOC() uses _aligned_malloc() on Windows, MICROPROFILE_FREE() should use _aligned_free(). On VS2017 at least, I would get an assert when free() was called otherwise. I wondered if this was something new for VS2017, but _aligned_free seems to exist since VS .NET 2003 so it should be fine.

    Sorry for the multiple commits. My first commit didn't preserve tabs for indentation (I use 4 spaces) so it showed useless whitespace changes. The last commit looks fine.

    opened by Skylark13 3
  • Compilation fails on linux

    Compilation fails on linux

    In file included from src/modules/core/Trace.cpp:24:
    src/modules/core/trace/microprofile.cpp:1838:19: warning: comparison of integers of different signs: 'int64_t' (aka 'long') and 'unsigned long' [-Wsign-compare]
            MP_ASSERT(nCount < MICROPROFILE_GPU_BUFFER_SIZE);
            ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    src/modules/core/trace/microprofile.cpp:199:30: note: expanded from macro 'MP_ASSERT'
    #define MP_ASSERT(a) do{if(!(a)){MP_BREAK();} }while(0)
                                 ^
    src/modules/core/trace/microprofile.cpp:3699:2: error: use of undeclared identifier 'send'
            send(Socket, &S.WebServerBuffer[0], S.WebServerPut, 0);
            ^
    src/modules/core/trace/microprofile.cpp:3711:3: error: use of undeclared identifier 'send'
                    send(Socket, pData, (int)nSize, 0);
                    ^
    src/modules/core/trace/microprofile.cpp:3870:28: error: use of undeclared identifier 'PF_INET'
            S.ListenerSocket = socket(PF_INET, SOCK_STREAM, 6);
                                      ^
    src/modules/core/trace/microprofile.cpp:3870:37: error: use of undeclared identifier 'SOCK_STREAM'
            S.ListenerSocket = socket(PF_INET, SOCK_STREAM, 6);
                                               ^
    src/modules/core/trace/microprofile.cpp:3871:13: error: use of undeclared identifier 'MP_INVALID_SOCKET'
            MP_ASSERT(!MP_INVALID_SOCKET(S.ListenerSocket));
                       ^
    src/modules/core/trace/microprofile.cpp:3875:21: error: variable has incomplete type 'struct sockaddr_in'
            struct sockaddr_in Addr; 
                               ^
    src/modules/core/trace/microprofile.cpp:3875:9: note: forward declaration of 'sockaddr_in'
            struct sockaddr_in Addr; 
                   ^
    src/modules/core/trace/microprofile.cpp:3876:20: error: use of undeclared identifier 'AF_INET'
            Addr.sin_family = AF_INET; 
                              ^
    src/modules/core/trace/microprofile.cpp:3877:25: error: use of undeclared identifier 'INADDR_ANY'
            Addr.sin_addr.s_addr = INADDR_ANY; 
                                   ^
    src/modules/core/trace/microprofile.cpp:3880:19: error: use of undeclared identifier 'htons'
                    Addr.sin_port = htons(MICROPROFILE_WEBSERVER_PORT+i); 
                                    ^
    src/modules/core/trace/microprofile.cpp:3881:35: error: use of undeclared identifier 'sockaddr'
                    if(0 == bind(S.ListenerSocket, (sockaddr*)&Addr, sizeof(Addr)))
                                                    ^
    src/modules/core/trace/microprofile.cpp:3881:44: error: expected expression
                    if(0 == bind(S.ListenerSocket, (sockaddr*)&Addr, sizeof(Addr)))
                                                             ^
    src/modules/core/trace/microprofile.cpp:3887:2: error: use of undeclared identifier 'listen'
            listen(S.ListenerSocket, 8);
            ^
    src/modules/core/trace/microprofile.cpp:4996:17: warning: comparison of integers of different signs: 'uint64_t' (aka 'unsigned long') and 'int' [-Wsign-compare]
                    if(nSizeBytes != r)
                       ~~~~~~~~~~ ^  ~
    src/modules/core/trace/microprofile.cpp:5015:13: warning: comparison of integers of different signs: 'unsigned long' and 'char' [-Wsign-compare]
            if(nSize+1 > BytesAllocated)
               ~~~~~~~ ^ ~~~~~~~~~~~~~~
    src/modules/core/trace/microprofile.cpp:5448:33: warning: comparison of integers of different signs: 'int' and 'uint32_t' (aka 'unsigned int') [-Wsign-compare]
                            uint32_t parent = CI.nParent == (uint32_t)-1 ? 0 : MicroProfileWebSocketIdPack(TYPE_COUNTER, CI.nParent);
                                              ~~~~~~~~~~ ^  ~~~~~~~~~~~~
    src/modules/core/trace/microprofile.cpp:5474:6: error: use of undeclared identifier 'MP_INVALID_SOCKET'
            if(!MP_INVALID_SOCKET(Connection))
                ^
    
    

    The error here is a problem with the header inclusion guard in line 845. There is only #if defined(__APPLE__) where it should have been #if defined(__APPLE__) || defined(__linux__)

    If you add this, you get a lot of unresolved symbols:

    
    ../../../Debug/lib/libcore.a(Trace.cpp.o): In function `MicroProfileTickToMsMultiplierGpu':
    src/modules/core/trace/microprofile.cpp:748: undefined reference to `MicroProfileTicksPerSecondGpu'
    ../../../Debug/lib/libcore.a(Trace.cpp.o): In function `MicroProfileShutdown':
    src/modules/core/trace/microprofile.cpp:1026: undefined reference to `MicroProfileGpuShutdown'
    ../../../Debug/lib/libcore.a(Trace.cpp.o): In function `MicroProfileAllocInternal(unsigned long, unsigned long)':
    src/modules/core/trace/microprofile.cpp:1932: undefined reference to `MicroProfileAllocAligned(unsigned long, unsigned long)'
    ../../../Debug/lib/libcore.a(Trace.cpp.o): In function `MicroProfileGpuEnterInternal':
    src/modules/core/trace/microprofile.cpp:1858: undefined reference to `MicroProfileGpuInsertTimeStamp'
    ../../../Debug/lib/libcore.a(Trace.cpp.o): In function `MicroProfileGpuLeaveInternal':
    src/modules/core/trace/microprofile.cpp:1878: undefined reference to `MicroProfileGpuInsertTimeStamp'
    ../../../Debug/lib/libcore.a(Trace.cpp.o): In function `MicroProfileFlip':
    src/modules/core/trace/microprofile.cpp:2122: undefined reference to `MicroProfileGpuFlip'
    src/modules/core/trace/microprofile.cpp:2163: undefined reference to `MicroProfileGpuGetTimeStamp'
    src/modules/core/trace/microprofile.cpp:2164: undefined reference to `MicroProfileTicksPerSecondGpu'
    src/modules/core/trace/microprofile.cpp:2272: undefined reference to `MicroProfileGpuGetTimeStamp'
    ../../../Debug/lib/libcore.a(Trace.cpp.o): In function `MicroProfileCalcAllTimers(float*, float*, float*, float*, float*, float*, float*, float*, float*, unsigned int)':
    src/modules/core/trace/microprofile.cpp:2650: undefined reference to `MicroProfileTicksPerSecondGpu'
    ../../../Debug/lib/libcore.a(Trace.cpp.o): In function `MicroProfileGetTime':
    src/modules/core/trace/microprofile.cpp:2703: undefined reference to `MicroProfileTicksPerSecondGpu'
    ../../../Debug/lib/libcore.a(Trace.cpp.o): In function `MicroProfileDumpCsv(void (*)(void*, unsigned long, char const*), void*)':
    src/modules/core/trace/microprofile.cpp:2968: undefined reference to `MicroProfileTicksPerSecondGpu'
    ../../../Debug/lib/libcore.a(Trace.cpp.o): In function `MicroProfileDumpHtml(void (*)(void*, unsigned long, char const*), void*, unsigned long, char const*, unsigned long)':
    src/modules/core/trace/microprofile.cpp:3096: undefined reference to `MicroProfileTicksPerSecondGpu'
    src/modules/core/trace/microprofile.cpp:3435: undefined reference to `MicroProfileTicksPerSecondGpu'
    src/modules/core/trace/microprofile.cpp:3437: undefined reference to `MicroProfileGetGpuTickReference'
    ../../../Debug/lib/libcore.a(Trace.cpp.o): In function `MicroProfileWebSocketSendFrame(int)':
    src/modules/core/trace/microprofile.cpp:5180: undefined reference to `MicroProfileTicksPerSecondGpu'
    ../../../Debug/lib/libcore.a(Trace.cpp.o): In function `core::traceGLInit()':
    src/modules/core/Trace.cpp:109: undefined reference to `MicroProfileGpuShutdown'
    ../../../Debug/lib/libcore.a(Trace.cpp.o): In function `core::traceGLShutdown()':
    src/modules/core/Trace.cpp:120: undefined reference to `MicroProfileGpuShutdown'
    
    

    Is there anything i'm missing here?

    opened by mgerhardy 3
  • html: replace non-free JavaScript functions

    html: replace non-free JavaScript functions

    opened by Tachi107 0
  • microprofile embeds non-free code

    microprofile embeds non-free code

    Hi, microprofile currently contains some non-free JavaScript code embedded in src/microprofile*.html, specifically the HSL to/from RGB functions:

    https://github.com/jonasmr/microprofile/blob/b20a06d66fe41b07e9e8fce5248908c44f2531d5/src/microprofile.html#L103-L158

    The code from https://gist.github.com/mjackson/5311256 is not licensed, meaning that it cannot be used for any purpose; on the Gist thread, people asked multiple times for a license, but the author never did so.

    On that same thread, user @vahidk linked to an alternative implementation free to use for any purpose: https://gist.github.com/mjackson/5311256?permalink_comment_id=2710361#gistcomment-2710361. I'd suggest using that instead.

    This has been originally reported on Debian: https://bugs.debian.org/1023178

    opened by Tachi107 0
  • Can‘t build microprofile with mingw64

    Can‘t build microprofile with mingw64

    My mingw64 is download from WinLibs

    when I build this project with

    cmake .. -G "Ninja"
    ninja
    

    the error is

    [1/2] Building CXX object CMakeFiles/microprofile.dir/microprofile.cpp.obj
    FAILED: CMakeFiles/microprofile.dir/microprofile.cpp.obj
    D:\mingw64\bin\c++.exe -DMICROPROFILE_EXPORT -ID:/C++_proj/microprofile -ID:/C++_proj/microprofile/build  -MD -MT CMakeFiles/microprofile.dir/microprofile.cpp.obj -MF CMakeFiles\microprofile.dir\microprofile.cpp.obj.d -o CMakeFiles/microprofile.dir/microprofile.cpp.obj -c D:/C++_proj/microprofile/microprofile.cpp
    D:/C++_proj/microprofile/microprofile.cpp: In function 'void MicroProfileThreadStart(void**, MicroProfileThreadFunc)':
    D:/C++_proj/microprofile/microprofile.cpp:1206:53: error: invalid conversion from 'MicroProfileThreadFunc' {aka 'void* (*)(void*)'} to 'LPVOID' {aka 'void*'} [-fpermissive]
     1206 |     *pThread = CreateThread(0, 0, ThreadTrampoline, Func, 0, 0);
          |                                                     ^~~~
          |                                                     |
          |                                                     MicroProfileThreadFunc {aka void* (*)(void*)}
    In file included from d:\mingw64\x86_64-w64-mingw32\include\winbase.h:29,
                     from d:\mingw64\x86_64-w64-mingw32\include\windows.h:70,
                     from d:\mingw64\x86_64-w64-mingw32\include\winsock2.h:23,
                     from D:/C++_proj/microprofile/microprofile.cpp:227:
    d:\mingw64\x86_64-w64-mingw32\include\processthreadsapi.h:279:150: note:   initializing argument 4 of 'void* CreateThread(LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD)'
      279 |   WINBASEAPI HANDLE WINAPI CreateThread (LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);
          |                                                                                                                                               ~~~~~~~^~~~~~~~~~~
    D:/C++_proj/microprofile/microprofile.cpp: At global scope:
    D:/C++_proj/microprofile/microprofile.cpp:1296:40: warning: 'thread' attribute directive ignored [-Wattributes]
     1296 | MP_THREAD_LOCAL MicroProfileThreadLog* g_MicroProfileThreadLogThreadLocal = 0;
          |                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    D:/C++_proj/microprofile/microprofile.cpp: In function 'bool MicroProfileStartWin32Trace(EventCallback, BufferCallback)':
    D:/C++_proj/microprofile/microprofile.cpp:7350:19: warning: passing NULL to non-pointer argument 1 of 'ULONG StopTraceA(TRACEHANDLE, LPCSTR, PEVENT_TRACE_PROPERTIES)' [-Wconversion-null]
     7350 |         StopTrace(NULL, KERNEL_LOGGER_NAME, &sessionProperties);
          |                   ^~~~
    In file included from D:/C++_proj/microprofile/microprofile.cpp:7241:
    d:\mingw64\x86_64-w64-mingw32\include\evntrace.h:858:49: note:   declared here
      858 |   EXTERN_C ULONG WMIAPI StopTraceA (TRACEHANDLE TraceHandle, LPCSTR InstanceName, PEVENT_TRACE_PROPERTIES Properties);
          |                                     ~~~~~~~~~~~~^~~~~~~~~~~
    ninja: build stopped: subcommand failed.
    
    opened by deltaLRD 1
  • chore: update LICENSE (MIT)

    chore: update LICENSE (MIT)

    Microprofile has been relicensed under the MIT (Expat) license three years ago in commit 2b64aaae25fc656404cdb94423db9040f196850f, but the README and the LICENSE file have never been updated to reflect the change

    opened by Tachi107 3
  • Count is incremented extra for timers that overlap calls to MicroProfileFlip

    Count is incremented extra for timers that overlap calls to MicroProfileFlip

    Hello, I either found an issue where timers report numbers incorrectly, or I'm misunderstanding something. TL;DR - S.Frame[nTimerIndex].nCount seems wrong for timers that overlap a call to MicroProfileFlip()

    --

    I have a background thread doing work like this:

    {
    MicroProfileEnter(token);
    StuffThatTakesOneSecond();
    MicroProfileLeave();
    }
    

    The main thread is calling MicroProfileFlip(nullptr) at 60 FPS.

    The main thread is also polling for activity on my token's name via a custom function like MicroProfileGetTime which also returns S.Frame[nTimerIndex].nCount so I know how often the code is called.

    The problem I run into is that it looks like the StuffThatTakesOneSecond shows up 61 times in the log, for an average of 16.3 ms per call, while the truth is that it is only called one time, taking 1 second.

    This appears to be due to line 3250 S.Frame[nTimerIndex].nCount += 1; https://github.com/jonasmr/microprofile/blob/master/microprofile.cpp#L3250 Every still-going timer's nCount is incremented when a flip happens, which is throwing off my numbers.

    If I comment out that line, then I get the expected results when I poll for data - I get something like time=0.016f, count=0 for sixty frames in a row, then time=something, count=1. My total collected data tells me StuffThatTakesOneSecond ran for a second, and was called once.

    This (maybe) bug also has the side-effect of skewing how often code seems to be run, based on how long that instrumented code takes. I found some code with an average time of 9 ms getting called 16,000 times. After optimization it took 2 ms, but was only called 8,000 times. The calling behavior never changed, and the truth was that the code was only running about 7,200 times both before and after the optimization.

    --

    Question 1 - Does this seem like a bug in MicroProfile, or does it seem like I'm misunderstanding something? Question 2 - If this is a bug, is line 3255 also unnecessary? pFrameGroupThread[nGroup].nCount += 1; https://github.com/jonasmr/microprofile/blob/master/microprofile.cpp#L3255 I couldn't figure out the right way to verify whether the HTML view is affected by this, but it seems like if one line should be removed, the other should be too.

    Thanks in advance -Eric

    opened by EricRehmeyer 1
Releases(v4.0)
  • v4.0(Oct 19, 2022)

    • Timeline view is now drawn using a hierarchical algorithm that scales better
    • Search in timeline view has been improved
      • you can now search for substrings interactively
      • search result now highlights by changing the color
      • and there is no longer any limit on the amount of search results
    • Added section markers, that allow you to group sections of code indepently of group/timer name.
    • Added CStr markers. This lets you pass in a static CStr, which will appear in the timeline view
      • Note that the caller is responsible for ensuring the CStr stays allocated, as it will be deferenced when generating a capture
      • only works in the timeline view, and is not usable in the various aggregation + live view
    • Fixed thread hide mode to be collapsed(which is what it should've been). Added a shortcut key to toggle it ('c')
    • Switched build to use github actions
    Source code(tar.gz)
    Source code(zip)
  • v3.1(Jul 13, 2019)

    Rewrite of menu in capture view Better handling of captures with extreme amount of threads Autocapture support for multiple captures and delay of capture Firefox support Gpu timers can now be inserted via callbacks. This makes it easier to integrate with multi dll projects like UE Percentile graph in live view

    Source code(tar.gz)
    Source code(zip)
Owner
Jonas Meyer
Jonas Meyer
Palanteer is a set of high performance visual profiler, debugger, tests enabler for C++ and Python

Palanteer is a set of lean and efficient tools to improve the general software quality, for C++ and Python programs.

Damien Feneyrou 1.9k Dec 29, 2022
Templight 2.0 - Template Instantiation Profiler and Debugger

Templight is a Clang-based tool to profile the time and memory consumption of template instantiations and to perform interactive debugging sessions to gain introspection into the template instantiation process.

Sven Mikael Persson 611 Dec 30, 2022
Single C file, Realtime CPU/GPU Profiler with Remote Web Viewer

Remotery A realtime CPU/GPU profiler hosted in a single C file with a viewer that runs in a web browser. Supported Platforms: Windows Windows UWP (Hol

Celtoys 2.4k Jan 8, 2023
Code profiler based on Frida

Code Profiler Based on Frida This repository contains the code to profile LIEF functions with Frida. Get Started Make sure to download the right versi

LIEF 26 Sep 12, 2022
Orbit, the Open Runtime Binary Instrumentation Tool, is a standalone C/C++ profiler for Windows and Linux

Orbit, the Open Runtime Binary Instrumentation Tool, is a standalone C/C++ profiler for Windows and Linux. Its main purpose is to help developers visualize the execution flow of a complex application.

Google 3k Dec 30, 2022
Palanteer is a set of high performance visual profiler, debugger, tests enabler for C++ and Python

Palanteer is a set of lean and efficient tools to improve the general software quality, for C++ and Python programs.

Damien Feneyrou 1.9k Dec 29, 2022
Bytehound - a memory profiler for Linux

Bytehound - a memory profiler for Linux Features Can be used to analyze memory leaks, see where exactly the memory is being consumed, identify tempora

Koute 3.3k Jan 4, 2023
Optick: C++ Profiler For Games

C++ Profiler For Games

Vadim Slyusarev 2.5k Jan 7, 2023
A small program that acts as a C profiler.

Simple Performance Test Description This is a simple program in C for performance testing which only works for x86 and x86_64 systems. A for loop is e

Christian Deacon 8 Oct 24, 2022
Parca-agent - eBPF based always-on profiler auto-discovering targets in Kubernetes and systemd, zero code changes or restarts needed!

Parca Agent Parca Agent is an always-on sampling profiler that uses eBPF to capture raw profiling data with very low overhead. It observes user-space

Parca 254 Jan 1, 2023
A profiler to disclose and quantify hardware features on GPUs.

ArchProbe ArchProbe is a profiling tool to demythify mobile GPU architectures with great details. The mechanism of ArchProbe is introduced in our tech

Microsoft 58 Dec 2, 2022
Lightweight profiler library for c++

easy_profiler About Key features Usage Integration General build system CMake Inserting blocks Storing variables Collect profiling data Streaming over

Sergey Yagovtsev 1.8k Jan 7, 2023
Templight 2.0 - Template Instantiation Profiler and Debugger

Templight is a Clang-based tool to profile the time and memory consumption of template instantiations and to perform interactive debugging sessions to gain introspection into the template instantiation process.

Sven Mikael Persson 611 Dec 30, 2022
Simple, small, C++ embeddable webserver with WebSockets support

Seasocks - A tiny embeddable C++ HTTP and WebSocket server for Linux Features Simple C++ API Serves static content from disk API for building WebSocke

Matt Godbolt 624 Jan 3, 2023
Duktape - embeddable Javascript engine with a focus on portability and compact footprint

Duktape ⚠️ Master branch is undergoing incompatible changes for Duktape 3.x. To track Duktape 2.x, follow the v2-maintenance branch. Introduction Dukt

Sami Vaarala 5.5k Jan 6, 2023
An embeddable fulltext search engine. Groonga is the successor project to Senna.

README Groonga is an open-source fulltext search engine and column store. Reference manual See doc/source/ directory or http://groonga.org/docs/. Here

Groonga Project 724 Dec 23, 2022
Embeddable Event-based Asynchronous Message/HTTP Server library for C/C++

libasyncd Embeddable Event-based Asynchronous Message/HTTP Server library for C/C++. What is libasyncd? Libasyncd is an embeddable event-driven asynch

Seungyoung 166 Dec 5, 2022
Elk is a tiny embeddable JavaScript engine that implements a small but usable subset of ES6

Elk is a tiny embeddable JavaScript engine that implements a small but usable subset of ES6. It is designed for microcontroller development. Instead of writing firmware code in C/C++, Elk allows to develop in JavaScript. Another use case is providing customers with a secure, protected scripting environment for product customisation.

Cesanta Software 1.5k Jan 8, 2023
theora-player is an embeddable theora video player C++ library based on the libtheora sample. It has no audio support at this moment.

theora-player Description theora-player is an embeddable theora video player C++ library based on the libtheora sample. It has no audio support at thi

Fire Falcom 2 Jun 18, 2022
Zep is a simple embeddable editor, with a rendering agnostic design and optional Vim mode

Zep - A Mini Editor Zep is a simple embeddable editor, with a rendering agnostic design and optional Vim mode. It is built as a shared modern-cmake li

null 1 Feb 26, 2022