Giter Club home page Giter Club logo

optick's Introduction

GitHub GitHub release
Optick is a super-lightweight C++ profiler for Games.
It provides access for all the necessary tools required for efficient performance analysis and optimization:
instrumentation, switch-contexts, sampling, GPU counters.

Looking for 'Brofiler'? It has been renamed to 'Optick', so you are in the right place.

Build Status

Windows (x64: msvc) Linux (x64: clang, gcc) MacOS (x64: clang, gcc) Static Code Analysis
Windows Build status Linux+MacOS Build Status Linux+MacOS Build Status Total alerts Codacy Badge
Features Windows Linux MacOS XBox PS4 UE4
Instrumentation ✔️ ✔️ ✔️ ✔️ ✔️
Switch Contexts ✔️ ETW ✔️ FTrace ✔️ DTrace ✔️ ✔️ Win
Sampling ✔️ ETW ✔️ Win
GPU ✔️ D3D12, Vulkan ✔️ Vulkan ✔️ Vulkan

✔️ - works out of the box, ⏳ - in progress, ❔ - coming soon for the certified developers

List of Games and Studios using Optick(Brofiler)

Allods Team 4A Games CryEngine Larian Studios Skyforge Metro Exodus Warface Armored Warfare

Video Tutorial

Optick Video Tutorial

Basic Integration (one line of code)

  1. Copy 'src' folder from the repository or latest release to your game project
  2. Add OPTICK_FRAME("MainThread"); macro to the main loop of your game and #include "optick.h" header
#include "optick.h"
...
while( true ) 
{
	OPTICK_FRAME("MainThread");
	engine.Update();
}
  1. Use OPTICK_EVENT(); macro to instrument a function
void SlowFunction()
{ 
	OPTICK_EVENT();
	...
}
  1. Add OPTICK_THREAD("Name"); macro to declare a new thread with Optick
void WorkerThread(...)
{
	OPTICK_THREAD("Worker");
	while (isRunning)
	{
		...
	}
}
  1. Edit optick.config.h to enable/disable some of the features in specific configs or platforms.
    (e.g. disabling Optick in final builds)

⚠️ If your Game uses dynamic linking and you are planning to use Optick from multiple dlls within the same executable - please make sure that Optick's code is added to the common Dynamic Library and this library is compiled with OPTICK_EXPORT define (Static Library won't work).
You could also use precompiled OptickCore.dll which is packaged with every release:

  • Add include folder to the extra include dirs of your project
  • Add lib/x64/debug and lib/x64/release to the extra library dirs of your project
  • Copy lib/x64/debug/OptickCore.dll and lib/x64/release/OptickCore.dll to the debug and release output folders of your project respectively

API

All the available API calls are documented here:
https://github.com/bombomby/optick/wiki/Optick-API

Unreal Engine

Optick provides a special plugin for UE4. Check more detailed documentation here:
https://github.com/bombomby/optick/wiki/UE4-Optick-Plugin
https://github.com/bombomby/optick/wiki/UE5-Optick-Plugin

Samples

Run GenerateProjects_gpu.bat to generate project files. To compile the samples you'll need to install VulkanSDK. Alternatively you could use GenerateProjects.bat to generate only minimal solution with ConsoleApp sample.
Open solution build\vs2017\Optick.sln with generated samples.

WindowsD3D12 WindowsVulkan ConsoleApp
WindowsD3D12 WindowsVulkan ConsoleApp
DirectX12 multithreading sample with Optick integration SaschaWillems's vulkan multithreading sample with Optick integration Basic ConsoleApp with Optick integration (Windows, Linux, MacOS)

Brofiler

Brofiler has been renamed into Optick starting from v1.2.0.
All the future development is going under the new name.
Cheatsheet for upgrading to the new version:

  • BROFILER_FRAME("MainThread"); => OPTICK_FRAME("MainThread");
  • BROFILER_THREAD("WorkerThread"); => OPTICK_THREAD("WorkerThread");
  • BROFILER_CATEGORY("Physics", Brofiler::Color::Green); => OPTICK_CATEGORY("Physics", Optick::Category::Physics);
  • BROFILER_EVENT(NAME); => OPTICK_EVENT(NAME);
  • PROFILE; => OPTICK_EVENT();

How To Start?

You can find a short instruction here:
https://github.com/bombomby/optick/wiki/How-to-start%3F-(Programmers-Setup)

optick's People

Contributors

againey avatar antonyudintsev avatar bombomby avatar brodyhiggerson avatar dedmen avatar eddedev avatar growlitheharpo avatar henriquegemignani avatar honeybunch avatar ievin avatar jkunstwald avatar joel-riendeau avatar kb173 avatar lectem avatar malytomas avatar matthesseling avatar qbojj avatar samsonovsa avatar slonopotamus avatar ylz-at avatar ymartel06 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

optick's Issues

Update Wiki picture for Source View

The Source View picture on the Wiki pages still displays the old naming scheme, PROFILER_CATEGORY instead of BROFILER_CATEGORY.

You might want to replace that picture with a new one to lessen confusion.

Not recording session

OptickApp.png
Attachments: [OptickApp.png]
Once I have the app running and then click start profiling session, optick begins to capture frames. Then when I want to stop, there is a red sqaure icon, but it says start profiling session still and not 'stop'.

Then once I've clicked that and exited the app, optick is sat in this same place. Even if I save the session, close optick and reopen that session there is nothing there.

I've tried recording a session a few times now, but I always get stuck here. Is there something I am missing?

quick edit: This is when I have my project added to the Optick_vs2017 GUI solution and added a reference to the Optick c# project. I my project from that solution and then have a separate Optick application from 'optick-master\bin\vs2017\x64\Debug' that is what I start the profiling from.

Wrong path in GUI solution

Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InteractiveDataDisplay.WPF", "..\..\..\IDD\InteractiveDataDisplay.WPF\src\InteractiveDataDisplay.WPF.csproj", "{2D34544C-2DF2-4B20-A43A-6C8D2DF3DD82}"

The path to InteractiveDataDisplay.WPF.csproj in OptikApp_vs2017.sln is not correct relative to the solution. It should be InteractiveDataDisplay.WPF\InteractiveDataDisplay.WPF.csproj.

Does brofiler work on Linux?

Hi there,

Somebody linked this library but said that it was Windows-only, yet I see a commit mentioning compatibility two years ago for non-Windows platforms.

My application is currently Windows-only but will eventually be deployed to Linux, and I wouldn't want to integrate something that couldn't survive that move.

Many thanks!

option to record last N frames

Accepting the fact that the application is only capable of working with few hundred frames, it would be nice to have an option to run the profiler continuously and discard frames older than some configuration (time, frames or MB). This would allow to monitor the game for a long time and after experiencing problems to quickly stop the recording.
In the current setup, I have to start recording and hope that something bad happens in the game in the next few seconds only.
I hope this feature suggestion makes sense :D

Rework PlatformSelector Control

image

This control is responsible for selecting the target which we would like to connect to.
Model is desribed here - Profiler.Platform.Connection:

	        public class Connection
		{
			public Platform.Type Target { get; set; }
			public String Name { get; set; }
			public IPAddress Address { get; set; }
			public int Port { get; set; }
		}

Behaviour:
By default the listbox should contain two items:

  1. Current Host Name + IP Address + Default Port (31313)
  2. An element with name "Add Connection" + IP 127.0.0.1 + Default Port (31313)

To get current host name use function Environment.MachineName.
To get IP-address - please use the following function: List listIP = Platform.GetPCAddresses();
This function might return multiple IP-addresses in case we have more than one network card (including virtual network cards). We need to have an individual entry for each returned ip-address.

After selecting "Add Connection", selecting IP-address, Port and pressing start: if connection is succesful - you'll receive a routed message about the new connection.

		private void TimeLine_NewConnection(object sender, RoutedEventArgs e)
		{
			TimeLine.NewConnectionEventArgs args = e as TimeLine.NewConnectionEventArgs;
			// TODO: Implement new connection processing
			Debug.Print("New Connection: [{0}] {1}:{2} {3}", args.Connection.Target, args.Connection.Address, args.Connection.Port, args.Connection.Name);
		}

Example output: New Connection: [Windows] 127.0.0.1:31313 CopmuterName

Key features:

  1. Once a message with the information regarding the new connection is arrived - we need to create a new entry in the combobox and select it (if we already have an instance with the same "IPAddress+Port" - just update the entry).
  2. For each combobox item template we need to add a button with cross icon - alightment to the right ("appbar_close" icon name). When we hover this button - cross should become dark red. Pressing this button should remove the entry from the combobox.
  3. We should not be able to remove any of the 'core' items (Current Host Addresses, "Add Connection")
  4. Use the following icons for each platform: windows - "appbar_os_windows_8", linux - "appbar_os_ubuntu", macos - "appbar_social_apple", xbox - "appbar_controller_xbox", playstation - "appbar_social_playstation".
  5. Extra textboxes for IP and Port are visible only if we selected "Add Connection" item.
  6. Any modification to the list of connections or information update should be saved into local settings -
    "Profiler.Controls.Settings.LocalSettings.Connections". These settings has a special type which synchronizes values between multiple instances of the application. Any modification to the the data in this list should be confirmed with Save() call. This call might be expensive, so we need to run it as a Task.
  7. Subscribe on Profiler.Controls.Settings.LocalSettings.OnChanged event and update the combo-box when this event is triggered. Test that combobox list of items is synchronized between multiple instances of the BrofilerApp.

Port profile API to linux ?

It would be really great if the API could run on Linux. not aiming for gui application on Linux.
Just the API so Linux can be profiled.

optick.exe silently fail to open

Same problem with the binary release and the project build from source. The problem is that it fails to initialize because d3dcompiler43.dll was missing, putting it from my windows 10 sdk in the executable folder solved it.

[UnrealEngine] Error upon launching a Standalone game / Dedicated server

When I try to launch a standalone game, on a dedicated server through Unreal Engine, I immediately get the following error after installing Optick. The profiler doesn't have to actually be running for this, it always fails and I'm unable to launch my game (I have it setup to launch a dedicated server and 2 clients. The client launch in the end, but are unable to connect to the server which crashed on below ensure):

I'm running Unreal 4.23.0 with the latest version of Optick from the store.

[2019.11.28-09.31.30:629][  0]OptickLog: Display: OptickPlugin Loaded!
[2019.11.28-09.31.34:114][  0]LogStats: FPlatformStackWalk::StackWalkAndDump -  3.141 s
[2019.11.28-09.31.34:114][  0]LogOutputDevice: Error: === Handled ensure: ===
[2019.11.28-09.31.34:116][  0]LogOutputDevice: Error: 
[2019.11.28-09.31.34:117][  0]LogOutputDevice: Error: Ensure condition failed: !IsRunningGame() [File:D:/Repos/UnrealEngine-4.23.0/Engine/Source/Editor/MainFrame/Private/MainFrameModule.cpp] [Line: 426]
[2019.11.28-09.31.34:118][  0]LogOutputDevice: Error: The MainFrame module should only be loaded when running the editor.  Code that extends the editor, adds menu items, etc... should not run when running in -game mode or in a non-WITH_EDITOR build
[2019.11.28-09.31.34:120][  0]LogOutputDevice: Error: Stack: 
[2019.11.28-09.31.34:120][  0]LogOutputDevice: Error: [Callstack] 0x00007ffeae92f859 UE4Editor-MainFrame.dll!DispatchCheckVerify<bool,<lambda_0d0fafbdaaf6e8546bf728e28869b5b6> >() [D:\Repos\UnrealEngine-4.23.0\Engine\Source\Runtime\Core\Public\Misc\AssertionMacros.h:164]
[2019.11.28-09.31.34:121][  0]LogOutputDevice: Error: [Callstack] 0x00007ffeae91c9d9 UE4Editor-MainFrame.dll!FMainFrameModule::StartupModule() [D:\Repos\UnrealEngine-4.23.0\Engine\Source\Editor\MainFrame\Private\MainFrameModule.cpp:426]
[2019.11.28-09.31.34:122][  0]LogOutputDevice: Error: [Callstack] 0x00007ffed697c41f UE4Editor-Core.dll!FModuleManager::LoadModuleWithFailureReason() [D:\Repos\UnrealEngine-4.23.0\Engine\Source\Runtime\Core\Private\Modules\ModuleManager.cpp:550]
[2019.11.28-09.31.34:123][  0]LogOutputDevice: Error: [Callstack] 0x00007ffed697b5cd UE4Editor-Core.dll!FModuleManager::LoadModuleChecked() [D:\Repos\UnrealEngine-4.23.0\Engine\Source\Runtime\Core\Private\Modules\ModuleManager.cpp:375]
[2019.11.28-09.31.34:124][  0]LogOutputDevice: Error: [Callstack] 0x00007ffeb79453a3 UE4Editor-LevelEditor.dll!FLevelEditorModule::StartupModule() [D:\Repos\UnrealEngine-4.23.0\Engine\Source\Editor\LevelEditor\Private\LevelEditor.cpp:234]
[2019.11.28-09.31.34:127][  0]LogOutputDevice: Error: [Callstack] 0x00007ffed697c41f UE4Editor-Core.dll!FModuleManager::LoadModuleWithFailureReason() [D:\Repos\UnrealEngine-4.23.0\Engine\Source\Runtime\Core\Private\Modules\ModuleManager.cpp:550]
[2019.11.28-09.31.34:127][  0]LogOutputDevice: Error: [Callstack] 0x00007ffed697b5cd UE4Editor-Core.dll!FModuleManager::LoadModuleChecked() [D:\Repos\UnrealEngine-4.23.0\Engine\Source\Runtime\Core\Private\Modules\ModuleManager.cpp:375]
[2019.11.28-09.31.34:128][  0]LogOutputDevice: Error: [Callstack] 0x00007ffedd491a4b UE4Editor-OptickPlugin-0008.dll!FOptickPlugin::StartupModule() [C:\Users\Ivo\Documents\Repos\Vire\Plugins\OptickPlugin\Source\Private\OptickPlugin.cpp:232]
[2019.11.28-09.31.34:129][  0]LogOutputDevice: Error: [Callstack] 0x00007ffed697c41f UE4Editor-Core.dll!FModuleManager::LoadModuleWithFailureReason() [D:\Repos\UnrealEngine-4.23.0\Engine\Source\Runtime\Core\Private\Modules\ModuleManager.cpp:550]
[2019.11.28-09.31.34:130][  0]LogOutputDevice: Error: [Callstack] 0x00007fff4fe48e87 UE4Editor-Projects.dll!FModuleDescriptor::LoadModulesForPhase() [D:\Repos\UnrealEngine-4.23.0\Engine\Source\Runtime\Projects\Private\ModuleDescriptor.cpp:596]
[2019.11.28-09.31.34:131][  0]LogOutputDevice: Error: [Callstack] 0x00007fff4fe59283 UE4Editor-Projects.dll!TryLoadModulesForPlugin() [D:\Repos\UnrealEngine-4.23.0\Engine\Source\Runtime\Projects\Private\PluginManager.cpp:938]
[2019.11.28-09.31.34:131][  0]LogOutputDevice: Error: [Callstack] 0x00007fff4fe48c4e UE4Editor-Projects.dll!FPluginManager::LoadModulesForEnabledPlugins() [D:\Repos\UnrealEngine-4.23.0\Engine\Source\Runtime\Projects\Private\PluginManager.cpp:1003]
[2019.11.28-09.31.34:132][  0]LogOutputDevice: Error: [Callstack] 0x00007ff7b035d5da UE4Editor.exe!FEngineLoop::LoadStartupModules() [D:\Repos\UnrealEngine-4.23.0\Engine\Source\Runtime\Launch\Private\LaunchEngineLoop.cpp:3344]
[2019.11.28-09.31.34:132][  0]LogOutputDevice: Error: [Callstack] 0x00007ff7b0364483 UE4Editor.exe!FEngineLoop::PreInit() [D:\Repos\UnrealEngine-4.23.0\Engine\Source\Runtime\Launch\Private\LaunchEngineLoop.cpp:2738]
[2019.11.28-09.31.34:133][  0]LogOutputDevice: Error: [Callstack] 0x00007ff7b035a227 UE4Editor.exe!GuardedMain() [D:\Repos\UnrealEngine-4.23.0\Engine\Source\Runtime\Launch\Private\Launch.cpp:131]
[2019.11.28-09.31.34:134][  0]LogOutputDevice: Error: [Callstack] 0x00007ff7b035a5ba UE4Editor.exe!GuardedMainWrapper() [D:\Repos\UnrealEngine-4.23.0\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:147]
[2019.11.28-09.31.34:135][  0]LogOutputDevice: Error: [Callstack] 0x00007ff7b036b2ac UE4Editor.exe!WinMain() [D:\Repos\UnrealEngine-4.23.0\Engine\Source\Runtime\Launch\Private\Windows\LaunchWindows.cpp:279]
[2019.11.28-09.31.34:139][  0]LogOutputDevice: Error: [Callstack] 0x00007ff7b036dd8a UE4Editor.exe!__scrt_common_main_seh() [d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288]
[2019.11.28-09.31.34:140][  0]LogOutputDevice: Error: [Callstack] 0x00007fff660a7bd4 KERNEL32.DLL!UnknownFunction []
[2019.11.28-09.31.34:141][  0]LogOutputDevice: Error: [Callstack] 0x00007fff663cced1 ntdll.dll!UnknownFunction []
[2019.11.28-09.31.34:142][  0]LogOutputDevice: Error: 
[2019.11.28-09.31.34:152][  0]LogStats:                SubmitErrorReport -  0.000 s
[2019.11.28-09.31.35:573][  0]LogStats:                    SendNewReport -  1.421 s
[2019.11.28-09.31.35:573][  0]LogStats:             FDebug::EnsureFailed -  4.600 s

Tags are sometimes associated with incorrect event.

In the picture below, the tag pathCost is incorrectly associated with an event that is already out of scope.
optick-bad-tag-association

Pseudocode:

void pathfinding()
{
	OPTICK_EVENT("pathfinding");
	OPTICK_TAG("estDist", "a number");
	OPTICK_TAG("estCost", "a number");
	{
		OPTICK_EVENT("AStar");
		OPTICK_TAG("expandedNodes", "a number");
		OPTICK_TAG("largestQueue", "a number");
	}
	{
		OPTICK_EVENT("reconstruct");
	}
	OPTICK_TAG("pathCost", "a number");
	OPTICK_TAG("pathNodes", "a number");
}

Tested with commit tagged 1.2.5.0.

It took several attempts to make it happen, so I guess it is some sort of a race condition?

The Profiler namespace should be prefixed by :: to avoid name collision

Hello

If the brofiler macros is used inside a namespace that itself has a profiler namespace, there will be a name clash (the internal namespace will be preferred).
So I suggest to change the macros this way :

define BROFILER_THREAD(FRAME_NAME) ::Profiler::ThreadDescription currentFrameDescription(FRAME_NAME);\

(Profiler is now prefixed with ::)

Compilation error on Linux: ‘::abs’ has not been declared

GCC 8.3.0-6

In file included from /usr/include/c++/8/cstdlib:77,
                 from /usr/include/c++/8/stdlib.h:36,
                 from /[directory]/deps/src/optick/src/optick_miniz.h:479,
                 from /[directory]/deps/src/optick/src/optick_miniz.cpp:27:
/usr/include/c++/8/bits/std_abs.h:52:11: error: ‘::abs’ has not been declared
   using ::abs;
           ^~~

Linux build?

Looks like a great project, and I would be eager to see a Linux build. Is the source in a position to be compiled straight, or is there anything to make this actually Windows only?

Add ContextMenu to the Timeline Control

Add the following functionality (RMB) - refactor and reuse ContextMenu from FrameInfo.xaml:

  • Show Souce Code
  • Sample Function (This Frame)
  • Sample Function (All Frames)

Code is here: ThreadView.xaml.cs

Thread visualization is not working

When I use the brofiler I cannot see any thread visualization. Everything else works fine. I assume it should look similar to the following image.
assumed

The whole thread seems like a single invisible line instead of shiny, colorful, nested scopes. You can see the issue in the following image.
issue

I tried the latest master branch + the released 1.1.2 version and faced the same problem. Can it be a broken windows update ? I am using win10 pro v1709 Build 16299.125. Do you have any idea what can cause this ?

Thanks in advance.

Regarding exporting values as CSV

I was wondering if there is any way to export values recorded on Optick to CSV or some data form to create charts. For example a list of functions with their average times in the recorded session. It would be incredibly helpful for my research project in which I will be recording many different sessions to compare the results.

Thanks!

Attachments: open screenshot in a separate window

When we hover over screenshot thumbnail - cursor should change to the magnifier glass.
On LMB click on this thumbnail - open a new window with just a single Image.
The title of the window should contain current capture name and screenshot name.
Pressing 'Alt+F4' or 'Esc' should close the window.
Window should be resizeable. Image should not be stretched and should keep aspect ratio.

VS2015 Fixes

Needly replace:
hash_set on unordered_set

and in:

OutputDataStream& Sampler::Serialize replace 

std::vector<const Symbol * const> symbols;
on
#if _MSC_VER == 1900
        std::vector<const Symbol *> symbols;
#else
        std::vector<const Symbol * const> symbols;
#endif

Attachments: open in external app and export

Add a button (next to the combo-box - right side) to open current attachment in external app (System.Diagnostics.Process.Start).

Add a button (next to the combo-box - right side) to export selected attachment.
This button should open SaveFile dialog and allow you to select output folder and filename.
Control should automatically suggest existing filename.
Once the destination is selected - save the stream to the selected path.

Add a button (next to the combo-box - right side) to export all the attachments.

Add tooltips for each of the buttons.

Width and Height must be non-negative

When I somehow capture empty frames, this error happens:

Version 1.2.3

************** Exception Text **************
System.ArgumentException: Width and Height must be non-negative.
at System.Windows.Size..ctor(Double width, Double height)
at Profiler.DirectX.DynamicMesh.AddRect(Rect rect, Color color)
at Profiler.ThreadView.DrawSelection(DirectXCanvas canvas)
at Profiler.ThreadView.OnDraw(DirectXCanvas canvas, Layer layer)
at Profiler.DirectX.DirectXCanvas.RenderCanvas_Paint(Object sender, PaintEventArgs e)
at System.Windows.Forms.Control.OnPaint(PaintEventArgs e)
at SharpDX.Windows.RenderControl.OnPaint(PaintEventArgs e)
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.UserControl.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

optick-issue

Memory FlameGraph

Hi,

We recently started integrating optick in our engine and figured that the optick viewer would provide a good framework for integrating/visualizing the snapshots generated by our memory allocation tracker.

Are there any plans to add instrumentation of memory allocations ?
Assuming someone would be willing to contribute, would you be interested in this feature ?
If so, would you be be willing to provide suggestions for what the API should look like as well as a few pointers regarding the integration ?

Thanks,

Optick unable to resolve function names when using "/DEBUG:FASTLINK"

When your application link with "/DEBUG:FASTLINK" instead of "/DEBUG:FULL", Optick address resolving step takes a lot more time, but at the end, does not resolve any function names in the flame graph. Switching to "/DEBUG:FULL" and Optick is able to resolve them just fine, and faster.

An option to see the loaded or missing symbols and proceed with a reload would be useful also, like in Visual Studio.

Crash brofiling static constructor

I get a crash using this minimal example:

#include "Brofiler.h"
class Foo
{
public:
	Foo(){ BROFILER_CATEGORY(__FUNCSIG__, Brofiler::Color::Khaki) }
};

Foo foo;

int main( int argc, char * argv[] ) {}

Details on the crash:

Exception thrown: 'System.AccessViolationException' in BrofilerTest.exe
Additional information: Attempted to read or write protected memory. This often an indication that other memory is corrupt.
If there is a handler for this exception, the program may be safely continued.

I get the crash when brofiling the constructors of static members of global variables. I guess that this is because the BROFILER_CATEGORY call is done before the BrofilerCore library is loaded?

Is there any way to ensure the library is loaded before any global member is initialized?

Crash in ProfileServer.cpp: Server::Update() CRITICAL_SECTION(lock)

Hi,

I've got brofiler working fine with a trivial 32-bit application, but get a crash in a more complex program in the first call of Server::Update() in ProfilerServer.cpp with "Access violation writing location 0x00000014.".

The crash happens in the CRITICAL_SECTION(lock) call, and it looks like the 'lock' object is not initialized (in fact it looks like the entire Server object is not initialized, everything is initialized to zero, and the Server::Server() constructor is never called:

brofiler_1

On the other hand, the constructor Core::Core() is called, and the CRITICAL_SECTION(lock) in Core::Update() works fine.

In the simpler program which works, the Server object is initialized when Server::Update() is called (although a breakpoint in the constructor is also never triggered, so this is a bit strange...):

brofiler_2

Any idea what's going on there, and how to fix or workaround?

Thanks!
-Floh.

Add Thread Filter to the Timeline

Add a filter to select a subset of threads.
Use SearchBox control with DelayedTextChanged event.
Hide all of the threads on the Timeline not containing specified string (should be case-insensitive).
Use space next to the Header row on the Timelne for the search box.

Code in: ThreadView.xaml.cs

Dynamic category

It's a feature request, not an actual bug. It would be nice if name argument in BROFILER_CATEGORY macro could change at runtime.

Not focusing Element in FrameInfo TreeView if it's out of view.

One would expect that if you select a Node in ThreadView it would focus in FrameInfo.
It does focus the object but it doesn't focus the view on it. Aka it doesn't scroll down to it.

Caused by https://github.com/bombomby/brofiler/blob/master/Brofiler/Frames/FrameInfo.xaml.cs#L227 not finding the item because
https://github.com/bombomby/brofiler/blob/master/Brofiler/Frames/FrameInfo.xaml#L95 virtualized them. VirtualizingStackPanel.IsVirtualizing="True"

https://stackoverflow.com/questions/6713365/itemcontainergenerator-containerfromitem-returns-null

Setting VirtualizingStackPanel.IsVirtualizing="False" kinda works. But now it fails on https://github.com/bombomby/brofiler/blob/master/Brofiler/Frames/FrameInfo.xaml.cs#L242
Manually seeking through the Items in the ItemContainerGenerator using the Debugger I can find the finalNode. But for whatever reason it can't select it.
This second error only happens after clicking onto an item in that thread for the first time. On the second click it works.
I think it might be because it just created the FrameInfo tab, the tree structure isn't completly initialized yet.

Okey managed to fix that too. By adding
EventTreeView.UpdateLayout(); in Line https://github.com/bombomby/brofiler/blob/master/Brofiler/Frames/FrameInfo.xaml.cs#L215

I'm not really a C# programmer. Maybe you have a better solution for this. If you think this is optimal I can do a PR for it.

App is slow

I just captured few thousands of frames and Optick.exe stuck on "Generating summary"....
Am I using Optick properly? Or it should collect only few dozens of frames?
image

UPD:
In few hundreds of frames it freezes less, but there is still some kind of incorrect fonts rendering (it's really hard to read).
image

Fiber support?

I'm using https://github.com/RichieSams/FiberTaskingLib throughout my code, and am trying to integrate Optick into the application.

Previously, I was using the OPTICK_THREAD macro when the worker threads started, but Optick seems to get confused when you resume a function on another thread after a switch where there is an OPTICK_EVENT at the beginning of that function (e.g. the scoped event starts and stops on two different threads).

This prompted me to go looking, and I found Optick::RegisterFiber, but there is no documentation on this function. How should one use this? Should it be used in addition to OPTICK_THREAD on the workers? What about combined with OPTICK_EVENT, OPTICK_CATEGORY, and OPTICK_TAG?

Compile error when compiling with GCC

This happens on the master branch with all versions of GCC I tried (GCC 6 through 9).
To reproduce:

$ ./tools/Linux/premake5 gmake && pushd build/gmake/ && make clean && CC=gcc-9 CXX=g++-9 make config=release_x64; popd
Building configurations...
Running action 'gmake'...
Done (25ms).
~/Projects/code/optick/build/gmake ~/Projects/code/optick ~/Projects/code/optick ~/Projects/code/optick
Cleaning OptickCore
Cleaning ConsoleApp
==== Building OptickCore (release_x64) ====
Creating Temp/x64/Release/OptickCore
optick_core.cpp
optick_gpu.cpp
optick_gpu.d3d12.cpp
optick_gpu.vulkan.cpp
optick_message.cpp
optick_serialization.cpp
optick_server.cpp
In file included from ../../src/optick_common.h:7,
                 from ../../src/optick_gpu.vulkan.cpp:356:
../../src/optick.h:493:2: error: multi-line comment [-Werror=comment]
  493 |  // HOT  \\
      |  ^
In file included from ../../src/optick_common.h:7,
                 from ../../src/optick_message.cpp:4:
../../src/optick.h:493:2: error: multi-line comment [-Werror=comment]
  493 |  // HOT  \\
      |  ^
In file included from ../../src/optick_common.h:7,
                 from ../../src/optick_gpu.d3d12.cpp:371:
../../src/optick.h:493:2: error: multi-line comment [-Werror=comment]
  493 |  // HOT  \\
      |  ^
In file included from ../../src/optick_common.h:7,
                 from ../../src/optick_message.h:6,
                 from ../../src/optick_server.h:5,
                 from ../../src/optick_server.cpp:4:
../../src/optick.h:493:2: error: multi-line comment [-Werror=comment]
  493 |  // HOT  \\
      |  ^
In file included from ../../src/optick_common.h:7,
                 from ../../src/optick_serialization.cpp:5:
../../src/optick.h:493:2: error: multi-line comment [-Werror=comment]
  493 |  // HOT  \\
      |  ^
cc1plus: all warnings being treated as errors
cc1plus: all warnings being treated as errors
make[1]: *** [OptickCore.make:144: Temp/x64/Release/OptickCore/optick_gpu.vulkan.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make[1]: *** [OptickCore.make:141: Temp/x64/Release/OptickCore/optick_gpu.d3d12.o] Error 1
In file included from ../../src/optick_common.h:7,
                 from ../../src/optick_gpu.h:9,
                 from ../../src/optick_gpu.cpp:4:
../../src/optick.h:493:2: error: multi-line comment [-Werror=comment]
  493 |  // HOT  \\
      |  ^
In file included from ../../src/optick_common.h:7,
                 from ../../src/optick_core.h:9,
                 from ../../src/optick_core.cpp:5:
../../src/optick.h:493:2: error: multi-line comment [-Werror=comment]
  493 |  // HOT  \\
      |  ^
../../src/optick_core.cpp: In static member function ‘static void Optick::Event::Stop(Optick::EventData&)’:
../../src/optick_core.cpp:234:20: error: unused variable ‘storage’ [-Werror=unused-variable]
  234 |  if (EventStorage* storage = Core::storage)
      |                    ^~~~~~~
../../src/optick_core.cpp: In static member function ‘static void Optick::Event::Push(const char*)’:
../../src/optick_core.cpp:261:20: error: unused variable ‘storage’ [-Werror=unused-variable]
  261 |  if (EventStorage* storage = Core::storage)
      |                    ^~~~~~~
cc1plus: all warnings being treated as errors
make[1]: *** [OptickCore.make:138: Temp/x64/Release/OptickCore/optick_gpu.o] Error 1
../../src/optick_core.cpp: In function ‘uint64_t Optick::MurmurHash64A(const void*, int, uint64_t)’:
../../src/optick_core.cpp:73:12: error: this statement may fall through [-Werror=implicit-fallthrough=]
   73 |  case 7: h ^= uint64_t(data2[6]) << 48;
      |          ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/optick_core.cpp:74:2: note: here
   74 |  case 6: h ^= uint64_t(data2[5]) << 40;
      |  ^~~~
../../src/optick_core.cpp:74:12: error: this statement may fall through [-Werror=implicit-fallthrough=]
   74 |  case 6: h ^= uint64_t(data2[5]) << 40;
      |          ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/optick_core.cpp:75:2: note: here
   75 |  case 5: h ^= uint64_t(data2[4]) << 32;
      |  ^~~~
../../src/optick_core.cpp:75:12: error: this statement may fall through [-Werror=implicit-fallthrough=]
   75 |  case 5: h ^= uint64_t(data2[4]) << 32;
      |          ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/optick_core.cpp:76:2: note: here
   76 |  case 4: h ^= uint64_t(data2[3]) << 24;
      |  ^~~~
../../src/optick_core.cpp:76:12: error: this statement may fall through [-Werror=implicit-fallthrough=]
   76 |  case 4: h ^= uint64_t(data2[3]) << 24;
      |          ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/optick_core.cpp:77:2: note: here
   77 |  case 3: h ^= uint64_t(data2[2]) << 16;
      |  ^~~~
../../src/optick_core.cpp:77:12: error: this statement may fall through [-Werror=implicit-fallthrough=]
   77 |  case 3: h ^= uint64_t(data2[2]) << 16;
      |          ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/optick_core.cpp:78:2: note: here
   78 |  case 2: h ^= uint64_t(data2[1]) << 8;
      |  ^~~~
../../src/optick_core.cpp:78:12: error: this statement may fall through [-Werror=implicit-fallthrough=]
   78 |  case 2: h ^= uint64_t(data2[1]) << 8;
      |          ~~^~~~~~~~~~~~~~~~~~~~~~~~~~
../../src/optick_core.cpp:79:2: note: here
   79 |  case 1: h ^= uint64_t(data2[0]);
      |  ^~~~
cc1plus: all warnings being treated as errors
make[1]: *** [OptickCore.make:147: Temp/x64/Release/OptickCore/optick_message.o] Error 1
cc1plus: all warnings being treated as errors
make[1]: *** [OptickCore.make:150: Temp/x64/Release/OptickCore/optick_serialization.o] Error 1
cc1plus: all warnings being treated as errors
make[1]: *** [OptickCore.make:153: Temp/x64/Release/OptickCore/optick_server.o] Error 1
cc1plus: all warnings being treated as errors
make[1]: *** [OptickCore.make:135: Temp/x64/Release/OptickCore/optick_core.o] Error 1
make: *** [Makefile:31: OptickCore] Error 2
~/Projects/code/optick ~/Projects/code/optick ~/Projects/code/optick

tag ordering

When there are multiple tags on one event, the gui app will show them in random order. This is often confusing. Would it be possible to sort the tags either alphabetically by their name or by the order in which they were added to the event in the application code? Thanks :D

optick-unordered-tags
(optick 1.2.4)

GUI perfomance

When profiling a great number of functions and zooming-in in the GUI, the application becomes non responsive. This is probably due to the density of the function blocks.

I can think of two elegant solutions: Single frame focus, Expandable blocks.
Single frame focus would allow the user to select a single frame to analyze in the GUI, thus reducing the number of blocks to work with in the GUI, increasing the performance.
Expandable blocks works similarly, where each higher level function block can be expanded to show the lower level. There can be an expand / contract all option too..

OPTICK_THREAD vs OPTICK_FRAME

Hi,
the wiki page makes no mention of OPTICK_FRAME, which is rather unfortunate since this is the one required macro to make the profiler work.

Also what is the difference between OPTICK_THREAD and OPTICK_FRAME?

I have multiple threads each dedicated to a specific task. (I know that this does not scale, but lets leave that aside for now.) One thread is rendering as fast as possible. One thread updates sound buffers at a fixed rate and one thread updates game logic and passes the state to be used by other threads. How should I use the two aforementioned macros in such situation? How do I control which of the frame sequences will be shown in the upper timeline?

When I use just one OPTICK_FRAME, I cannot see details from other threads.
When I use one OPTICK_FRAME in each of the threads, I cannot control which of the threads should be in the upper timeline.

Thanks

optick_event name changes

Hi,
would it be possible to disable changes for events with explicitly given names?

This shows empty boxes in the gui:

OPTICK_EVENT("long task (step 1)");
OPTICK_EVENT("long task (step 2)");
OPTICK_EVENT("long task (step 3)");

This should stay as is now:

OPTICK_EVENT(); // takes a simplified name of the function

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.