Differences

This shows you the differences between two versions of the page.

Link to this comparison view

ep:labs:07:contents:tasks:ex3 [2025/05/04 02:59]
radu.mantu
ep:labs:07:contents:tasks:ex3 [2025/05/06 15:01] (current)
radu.mantu
Line 1: Line 1:
-==== 03. [??p] Tracy ====+==== 03. [25p] Tracy ====
  
-TODOintro & maybe GLFW frame recording+**Tracy** is a feature-rich profiler that functions based on a client-server paradigm. The Server component is standalone and is used to analyze in real-time data collected during the execution of a program. When first started, the server will listen of a user-specified interface (defaultloopback iface) for incoming connections from clients. The Client component must be embedded into your application. In other words, you must consciously designate the regions that need to be analyzed and the metrics that you want observed. The client code will continuously collect runtime information and send it to the server. 
 + 
 +In this exercise we will walk through the process of adding **Tracy** support in an existing application,​ namely the OpenGL demo from the I/O monitoring lab. Specifically,​ we will observe the impact that doubling the number of vertices has on the CPU and GPU.
  
 Because time is short and we can't explore each feature of **Tracy**, check out this [[https://​tracy.nereid.pl/​|interactive demo]] offered by the authors as a web-based Server with a pre-loaded trace. Because time is short and we can't explore each feature of **Tracy**, check out this [[https://​tracy.nereid.pl/​|interactive demo]] offered by the authors as a web-based Server with a pre-loaded trace.
  
-=== [??p] Task A - Compile the Server ===+=== [5p] Task A - Compile the Server ===
  
 Clone the [[https://​github.com/​wolfpld/​tracy|Tracy]] project and jump into its root directory. Then, run the following commands to compile the Server component: Clone the [[https://​github.com/​wolfpld/​tracy|Tracy]] project and jump into its root directory. Then, run the following commands to compile the Server component:
Line 13: Line 15:
 $ cmake --build profiler/​build --config Release --parallel $ cmake --build profiler/​build --config Release --parallel
 </​code>​ </​code>​
 +
 +<note important>​
 +If the compilation process takes up too much RAM, try to reduce the parallelization.
 +</​note>​
  
 So far so good. Once we're done with the integration of the Client into our demo application,​ the Server will collect the trace data and process it for us. But first things first... So far so good. Once we're done with the integration of the Client into our demo application,​ the Server will collect the trace data and process it for us. But first things first...
  
-=== [??p] Task B - Client integration ===+=== [5p] Task B - Client integration ===
  
 Go to ''​lab_07/​task_03/''​ where you will find a copy of the OpenGL application from our previous I/O monitoring lab. This version no longer has the tracking code that generated runtime statistics for you to plot. Go to ''​lab_07/​task_03/''​ where you will find a copy of the OpenGL application from our previous I/O monitoring lab. This version no longer has the tracking code that generated runtime statistics for you to plot.
Line 26: Line 32:
 Recompile the project and make sure you don't have any errors. Recompile the project and make sure you don't have any errors.
  
-=== [??p] Task C - Add trace marksers ​===+=== [5p] Task C - Add trace markers ​===
  
 Now that we have the **Tracy** client code compiled into our application,​ it's time to add some markers. Because we defined the **TRACY_ENABLE** macro at a global scale, the **FrameMark** macro has the following definition in ''​Tracy.hpp'':​ Now that we have the **Tracy** client code compiled into our application,​ it's time to add some markers. Because we defined the **TRACY_ENABLE** macro at a global scale, the **FrameMark** macro has the following definition in ''​Tracy.hpp'':​
Line 38: Line 44:
 Similarly, place the **ZoneScoped** macro at the start of each function that you want included in the trace. This will include everything that executes within the scope of that function to the server, once **FrameMark** is reached. Similarly, place the **ZoneScoped** macro at the start of each function that you want included in the trace. This will include everything that executes within the scope of that function to the server, once **FrameMark** is reached.
  
-=== [??p] Task D - Collect and visualize samples ===+=== [5p] Task D - Collect and visualize samples ===
  
 Now that we've set up both the Server and the Client, it's time to test out **Tracy**. First, start **tracy-profiler** in your build directory from Task A. Hit the //Connect// button to listen for incoming connections from Clients on your localhost. Now that we've set up both the Server and the Client, it's time to test out **Tracy**. First, start **tracy-profiler** in your build directory from Task A. Hit the //Connect// button to listen for incoming connections from Clients on your localhost.
Line 51: Line 57:
 Because the Client that we integrated is bare-bones (i.e., cannot capture frames from the GLFW window, get GPU usage statistics, interpret DWARF symbols, etc.) the information seen in **Figure 1** is limited in scope. However, we can point out how the duration of **gen_sphere()** becomes increasingly longer as we continuously double the amount of generated vertices. These function calls coincide with intervals of increased CPU activity. Also, notice how **Tracy** is able to unwind the call stack and determine that **gen_sphere()** is called as a result of processing input events in **process_input()**,​ inside the main rendering loop. Because the Client that we integrated is bare-bones (i.e., cannot capture frames from the GLFW window, get GPU usage statistics, interpret DWARF symbols, etc.) the information seen in **Figure 1** is limited in scope. However, we can point out how the duration of **gen_sphere()** becomes increasingly longer as we continuously double the amount of generated vertices. These function calls coincide with intervals of increased CPU activity. Also, notice how **Tracy** is able to unwind the call stack and determine that **gen_sphere()** is called as a result of processing input events in **process_input()**,​ inside the main rendering loop.
  
-=== [??p] Task E - GPU sampling ===+=== [5p] Task E - GPU sampling ===
  
 Now that we have our CPU profiling set up, it's time to add GPU support as well. Following this task, we will be able to identify the time slices in which the GPU is performing computations to satisfy our OpenGL draw requests. In order to figure this out, we need to add three additional Tracy macros in our **main()** function. These macros are defined in ''​tracy/​TracyOpenGL.hpp'',​ so include it. Now that we have our CPU profiling set up, it's time to add GPU support as well. Following this task, we will be able to identify the time slices in which the GPU is performing computations to satisfy our OpenGL draw requests. In order to figure this out, we need to add three additional Tracy macros in our **main()** function. These macros are defined in ''​tracy/​TracyOpenGL.hpp'',​ so include it.
ep/labs/07/contents/tasks/ex3.1746316777.txt.gz · Last modified: 2025/05/04 02:59 by radu.mantu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0