OpenGL Performance Tools Jeff Kiel NVIDIA Corporation.
Transcript of OpenGL Performance Tools Jeff Kiel NVIDIA Corporation.
OpenGL Performance Tools
Jeff Kiel
NVIDIA Corporation
Copyright © NVIDIA Corporation 2004
Performance Tools Agenda
Problem statement
GPU pipelined architecture at a glance
NVPerfKit 2.0: Driver and GPU Performance DataGLExpert: OpenGL API Assistance
NVPerfSDK: Integrated into your applicationNVPerfAPI
PDH, NVDevCPL
Solutions to common bottlenecks
NVShaderPerf: Shader Performance
Copyright © NVIDIA Corporation 2004
What’s The Problem?
Why is my app running at 13FPS after CPU tuning?
How can I determine what is going in that GPU?
How come IHV engineers are able to figure it out?
Copyright © NVIDIA Corporation 2004
GPU architecture at a glance
Pipelined architecture: each unit needs the data from the previous unit to do its job
Method: Bottleneck identification and elimination
Goal: Balance the pipeline
Copyright © NVIDIA Corporation 2004
GPU Pipelined Architecture (simplified view)
FrameFramebufferbuffer
Pixel Pixel ShaderShader
Texture Texture Storage + Storage + FilteringFiltering
RasterizerRasterizerVertex Vertex ShaderShader
Vertex Vertex SetupSetupCPUCPU
VerticesVertices PixelsPixels
GPUGPU
…110010100100…
Copyright © NVIDIA Corporation 2004
GPU Pipelined Architecture (simplified view)
GPUGPU
One unit can limit the speed of the pipeline…One unit can limit the speed of the pipeline…
FrameFramebufferbuffer
Pixel Pixel ShaderShader
Texture Texture Storage + Storage + FilteringFiltering
RasterizerRasterizerVertex Vertex ShaderShader
Vertex Vertex SetupSetupCPUCPU
Copyright © NVIDIA Corporation 2004
Classic Bottleneck Identification
Modify target stage to decrease workload
FPS FPS
If performance/FPS improves greatly, this stage is the bottleneckCareful not to change the workload of other stages!
Copyright © NVIDIA Corporation 2004
Classic Bottleneck Identification
Rule out other stages, give them little or no work
FPS
If performance doesn’t change significantly, this stage is the bottleneckCareful not to change the workload of target stage!
FPS
Copyright © NVIDIA Corporation 2004
Sample performance data at different points along the pipeline while rendering
Compare amount of work done to maximum work possible
Query the GPU for unit bottleneck information
The answer? NVPerfKit!NVPerfHUD: The GPU Performance Accelerator
NVPerfAPI: Integrated in your application
Analyze your application like an NVIDIA Engineer!
Ideal Bottleneck Identification
Copyright © NVIDIA Corporation 2004
NVPerfKit
What’s new in NVPerfKit 2.0?
How do I integrate it?
Associated tools
Copyright © NVIDIA Corporation 2004
What is in the NVPerfKit package?
Instrumented DriverGLExpertNVPerfHUDNVPerfSDK NVPerfAPI Sample Code Helper Classes DocumentationTools
gDEBuggerNVIDIA Plug-In for Microsoft PIX for WindowsNVDevCPL
Copyright © NVIDIA Corporation 2004
NVPerfKit Instrumented Driver
Exposes GPU and Driver Performance Counters
Data exported via NVIDIA API and PDH
Supports OpenGL and Direct3D
Simplified Experiments (SimExp)
Collect GPU and driver data, retain performanceTrack per-frame statistics
Gather and collate at end of frame
Typical hit 1-2%
Copyright © NVIDIA Corporation 2004
GLExpert: What is it?
Helps eliminate performance issues on the CPUOpenGL portion of the Instrumented Driver
Output information to console/stdout or debuggerDifferent groups and levels of information detail
Controlled using tab in NVDevCPLWhat it can do (today)
GL Errors: print when they are raisedSoftware Fallbacks: indicate when the driver is in fall backGPU Programs: errors during compile or linkVBOs: show where they reside, mapping detailsFBOs: print reasons a configuration is unsupported
Feature list to grow with future drivers
Copyright © NVIDIA Corporation 2004
GLExpert: Message Detail
GLExpert messages are made of a few parts: Category and Message IDs are provided that uniquely tag a message and facilitate parsing
A Base Message is category-specific and provides a description of the general issue at hand
An Instance Message is situation-specific and details the particular objects, programs, or API usage involved
Documentation provided for Base Messages
Copyright © NVIDIA Corporation 2004
GLExpert: Message Example
Example Base Message:The current FBO state (e.g. attachments, texture targets) is UNSUPPORTED.
Example Instance Message:Reason: COLOR_ATTACHMENT0 attempting to bind to an unsupported texture target.
Example Final Message:OGLE: CategoryID 0x00000010 MessageID: 0x00840000
The current FBO state (e.g. attachments,
texture targets) is UNSUPPORTED. Reason:
COLOR_ATTACHMENT0 attempting to bind to an
unsupported texture target.
Copyright © NVIDIA Corporation 2004
GLExpert: NVDevCPL tab
Copyright © NVIDIA Corporation 2004
Project Status
Shipping with NVPerfKit 2.0
Windows for now, Linux to follow
Supports NV3x, NV4x, and G7x architectures
Integrated in Graphic Remedy‘s gDEBugger
What types of things are interesting?
Copyright © NVIDIA Corporation 2004
NVPerfKit: What it looks like...
Copyright © NVIDIA Corporation 2004
OpenGL CountersGeneral
FPSms per frame
DriverDriver sleep time (waiting for GPU) % of the frame time driver is waiting
CountsBatchesVerticesPrimitives
MemoryAGP memory used in MB and bytesVideo memory used and total in MB and bytes
Copyright © NVIDIA Corporation 2004
GPU CountersVertex Setup
Vertex Shader
Rasterizer
Pixel Shader
Frame Buffer
Texture
gpu_idlevertex_attribute_count
vertex_shader_busy
culled_primitive_countprimitive_counttriangle_countvertex_count
fast_z_countshaded_pixel_count
shader_waits_for_texture
pixel_shader_busy
shader_waits_for_roprop_busy
Supported GPUsGeForce 7900 GTX & GTQuadro FX 4500GeForce 7800 GTXGeForce 6800 Ultra & GTGeForce 6600
GPU
Copyright © NVIDIA Corporation 2004
NEW! Simplified Experiments
Unit utilization and bottleneck experiments along the pipelineGPU Bottleneck experiment
Adds all utilization and bottleneck experimentsExpert system analyzes the results
Exposed via NVPerfAPI
FramebufferFramebuffer
Pixel ShaderPixel Shader
Texture Texture Storage + Storage + FilteringFiltering
ZCullZCullVertex Vertex ShaderShader
Vertex Setup Vertex Setup (IDX)(IDX)
Raster Raster OperationsOperations
Copyright © NVIDIA Corporation 2004
How do I use NVPerfKit counters?
PDH: Performance Data Helper for WindowsWin32 API for exposing performance data to user applicationsStandard interface, many providers and clientsSample code and helper classes provided in NVPerfSDK
Perfmon: (aka Microsoft Management Console)Win32 PDH client applicationPerfmon’s sampling frequency is low (1X/s)Displays PDH based counter values:
OS: CPU usage, memory usage, swap file usage, network stats, etc.NVIDIA: all of the counters exported by NVPerfKit
Good for rapid prototyping
Copyright © NVIDIA Corporation 2004
Enable counters: NVDevCPL
Copyright © NVIDIA Corporation 2004
Graphing results: Perfmon
Copyright © NVIDIA Corporation 2004
NEW! NVPerfAPI
NVIDIA API for easy integration of NVPerfKit No more enable counters in NVDevCPL, run app separately
No more lag from PDH
Simplified ExperimentsTargeted, multipass experiments to determine GPU bottleneck
Automated analysis of results to show bottlenecked unit
Use casesReal time performance monitoring using GPU and driver counters, round robin sampling
Simplified Experiments for single frame analysis
Copyright © NVIDIA Corporation 2004
NVPerfAPI: Real Time
// Somewhere in setupNVPMAddCounterByName(“vertex_shader_busy”);NVPMAddCounterByName (“pixel_shader_busy”);NVPMAddCounterByName (“shader_waits_for_texture”);NVPMAddCounterByName (“gpu_idle”);
// In your rendering loop, sample using namesNVPMSample(NULL, &nNumSamples);NVPMGetCounterValueByName(“vertex_shader_busy”, 0, &nVSEvents, &nVSCycles); NVPMGetCounterValueByName(“pixel_shader_busy”, 0, &nPSEvents, &nPSCycles); NVPMGetCounterValueByName(“shader_waits_for_texture”, 0, &nTexEvents,
&nTexCycles); NVPMGetCounterValueByName(“gpu_idle”, 0, &nIdleEvents, &nIdleCycles);
Copyright © NVIDIA Corporation 2004
NVPerfAPI: Real Time
// Somewhere in setupnVSBusy = NVPMGetCounterByName(“vertex_shader_busy”);NVPMAddCounter(nVSBusy);nPSBusy = NVPMGetCounterByName(“pixel_shader_busy”);NVPMAddCounter(nPSBusy);nWaitTexture = NVPMGetCounterByName(“shader_waits_for_texture”);NVPMAddCounter(nWaitTexture);nGPUIdle = NVPMGetCounterByName(“gpu_idle”);NVPMAddCounter(nGPUIdle);
// In your rendering loop, sample using IDsNVPMSample(aSamples, &nNumSamples);for(ii = 0; ii < nNumSamples; ++ii) {
if(aSamples[ii].index == nVSBusy) {}if(aSamples[ii].index == nPSBusy) {}if(aSamples[ii].index == nWaitTexture) {}if(aSamples[ii].index == nGPUIdle) {}
}
Copyright © NVIDIA Corporation 2004
NVPerfAPI Demo: Real time sampling
Copyright © NVIDIA Corporation 2004
NVPerfAPI: Simplified Experiments
NVPMAddCounter(“GPU Bottleneck”);NVPMAllocObjects(50);
NVPMBeginExperiment(&nNumPasses);for(int ii = 0; ii < nNumPasses; ++ii) {
// Setup the scene, clear Zbuffer/render target
NVPMBeginPass(ii);
NVPMBeginObject(0);// Draw calls associated with object 0 and flushNVPMEndObject(0);
NVPMBeginObject(1);// Draw calls associated with object 1 and flushNVPMEndObject(1);
// ...
NVPMEndPass(ii);}
NVPMEndExperiment();NVPMGetCounterValueByName(“GPU Bottleneck”, 0, &nGPUBneck, &nGPUCycles);NVPMGetGPUBottleneckName(nGPUBneck, pcString); // Convert to name
// End scene/present/swap buffers
Copyright © NVIDIA Corporation 2004
NVPerfAPI: Simplified Experiments
NVPMGetCounterValueByName(“IDX BNeck”, 0, &nIDXBneckEvents, &nIDXBNeckCycles);NVPMGetCounterValueByName(“IDX SOL”, 0, &nIDXSOLEvents, &nIDXSOLCycles);
GPU Bottleneck experimentRun bottleneck and utilization experiments on all units
Process results to find bottlenecked unit
Individual unit information can be queried
Can run individual unit experiments
Events: % utilization or % bottleneck…best way to visualize data
Cycles: microseconds that the experiment ran, helps recompute the numerator for sorting
Copyright © NVIDIA Corporation 2004
NVPerfAPI Demo: SimExp
Copyright © NVIDIA Corporation 2004
Graphic Remedy’s gDEBugger
Copyright © NVIDIA Corporation 2004
Solutions to common bottlenecksCPU Bound?
In your code: VTune…VTune…VTune… Don’t assume!
LOD all calculations: Physics, animation, AI, you name it!
In driver code:Create all resources up front: textures, VBOs, FBOs, GPU programs
Reduce locking resources on the fly (don’t write to a surface the GPU is reading from, etc.)
Create bigger batches: texture atlas, stitch strips together with degenerates
Vertex shader constants = lookup table for matrices
Instancing
Transferring data to GPUSmallest vertex format possible
– Remove unnecessary data
– Use smallest data type possible
Derive attributes in vertex shader
16 bit indices
Copyright © NVIDIA Corporation 2004
Solutions to common bottlenecks
IDX Bound, Vertex Program Bound?Reduce vertex attribute count
Compute some attributes
Combine attributes (2 2D tex coords per attribute)
Use geometry LOD
Move invariant calculations to the CPU
Use indexed primitives, more cache friendly
Don’t do unnecessary matrix multiplies
Use vertex shader branching to bypass expensive calculations
Use NVShaderPerf!
Copyright © NVIDIA Corporation 2004
Solutions to common bottlenecks
Fragment Program Bound?Render depth first (no color writes = 2X speed)
Prebake complex math into textures
Move per pixel calculations to the vertex shader
Use partial precision where possible, try it you may like the result
Avoid unnecessary normalizations
Use LOD specific pixel shaders
Use NVShaderPerf!
Copyright © NVIDIA Corporation 2004
Solutions to common bottlenecks
Texture bound?Prefilter textures to reduce size
Mipmap on any texture/surface that might be minified
Compressed textures
Use float textures only when needed
Copyright © NVIDIA Corporation 2004
Solutions to common bottlenecks
Frame buffer bound?Render depth first (no color writes = 2X speed)
Only use alpha blending when necessary
Use alpha test
Disable depth writes when possible
Avoid clearing the color buffer (sky box?)
Render front to back to get better z culling
Use float textures only when needed
Copyright © NVIDIA Corporation 2004
NVShaderPerf
What is NVShaderPerf?
What’s new with version 1.8?
What’s coming with version 2.0?
Copyright © NVIDIA Corporation 2004
v2f BumpReflectVS(a2v IN,uniform float4x4 WorldViewProj,uniform float4x4 World,uniform float4x4 ViewIT)
{v2f OUT;// Position in screen space.OUT.Position = mul(IN.Position, WorldViewProj);// pass texture coordinates for fetching the normal mapOUT.TexCoord.xyz = IN.TexCoord;OUT.TexCoord.w = 1.0;// compute the 4x4 tranform from tangent space to object spacefloat3x3 TangentToObjSpace;// first rows are the tangent and binormal scaled by the bump scaleTangentToObjSpace[0] = float3(IN.Tangent.x, IN.Binormal.x, IN.Normal.x);TangentToObjSpace[1] = float3(IN.Tangent.y, IN.Binormal.y, IN.Normal.y);TangentToObjSpace[2] = float3(IN.Tangent.z, IN.Binormal.z, IN.Normal.z);OUT.TexCoord1.x = dot(World[0].xyz, TangentToObjSpace[0]);OUT.TexCoord1.y = dot(World[1].xyz, TangentToObjSpace[0]);OUT.TexCoord1.z = dot(World[2].xyz, TangentToObjSpace[0]);OUT.TexCoord2.x = dot(World[0].xyz, TangentToObjSpace[1]);OUT.TexCoord2.y = dot(World[1].xyz, TangentToObjSpace[1]);OUT.TexCoord2.z = dot(World[2].xyz, TangentToObjSpace[1]);OUT.TexCoord3.x = dot(World[0].xyz, TangentToObjSpace[2]);OUT.TexCoord3.y = dot(World[1].xyz, TangentToObjSpace[2]);OUT.TexCoord3.z = dot(World[2].xyz, TangentToObjSpace[2]);float4 worldPos = mul(IN.Position, World);// compute the eye vector (going from shaded point to eye) in cube spacefloat4 eyeVector = worldPos - ViewIT[3]; // view inv. transpose contains eye position in world space in last row.OUT.TexCoord1.w = eyeVector.x;OUT.TexCoord2.w = eyeVector.y;OUT.TexCoord3.w = eyeVector.z;return OUT;
}
///////////////// pixel shader //////////////////
float4 BumpReflectPS(v2f IN,uniform sampler2D NormalMap,uniform samplerCUBE EnvironmentMap,
uniform float BumpScale) : COLOR{
// fetch the bump normal from the normal mapfloat3 normal = tex2D(NormalMap, IN.TexCoord.xy).xyz * 2.0 - 1.0;normal = normalize(float3(normal.x * BumpScale, normal.y * BumpScale, normal.z)); // transform the bump normal into cube space// then use the transformed normal and eye vector to compute a reflection vector// used to fetch the cube map// (we multiply by 2 only to increase brightness)float3 eyevec = float3(IN.TexCoord1.w, IN.TexCoord2.w, IN.TexCoord3.w);float3 worldNorm;worldNorm.x = dot(IN.TexCoord1.xyz,normal);worldNorm.y = dot(IN.TexCoord2.xyz,normal);worldNorm.z = dot(IN.TexCoord3.xyz,normal);float3 lookup = reflect(eyevec, worldNorm);return texCUBE(EnvironmentMap, lookup);
}
NVShaderPerf
Inputs:•GLSL (fragments)•!!FP1.0•!!ARBfp1.0•Cg•HLSL•PS1.x,PS2.x,PS3.x•VS1.x,VS2.x, VS3.x
NVShaderPerf
GPU Arch:•GeForce 7X00•GeForce 6X00•Geforce FX series•Quadro FX series
Outputs:Outputs:•Resulting assembly codeResulting assembly code•# of cycles# of cycles•# of temporary registers# of temporary registers•Pixel throughputPixel throughput•Test all fp16 and all fp32Test all fp16 and all fp32
Copyright © NVIDIA Corporation 2004
NVShaderPerf: In your pipeline
Test current performance against shader cycle budgets
test optimization opportunities
Automated regression analysis
Copyright © NVIDIA Corporation 2004
New in NVShaderPerf 1.8
Support for GeForce 7X00 series, Quadro FX
Unified Compiler from ForceWare Rel 80 driver
Better support for branching performanceDefault computes maximum path through shader
Use –minbranch to compute minimum path
Copyright © NVIDIA Corporation 2004
///////////////////////////////////////////////////////////////////////////////// // determine where the iris is and update normals, and lighting parameters to simulate iris geometry ///////////////////////////////////////////////////////////////////////////////// float3 objCoord = objFlatCoord; float3 objBumpNormal = normalize( f3tex2D( g_eyeNermel, v2f.UVtex0 ) * 2.0 - float3( 1, 1, 1 ) ); objBumpNormal = 0.350000 * objBumpNormal + ( 1 - 0.350000 ) * objFlatNormal; half3 diffuseCol = h3tex2D( g_irisWhiteMap, v2f.UVtex0 ); float specExp = 20.0; half3 specularCol = h3tex2D( g_eyeSpecMap, v2f.UVtex0 ) * g_specAmount; float tea; float3 centerToSurfaceVec = objFlatNormal; // = normalize( v2f.objCoord ) float firstDot = centerToSurfaceVec.y; // = dot( centerToSurfaceVec, float3( 0, 1, 0 ) ) if( firstDot > 0.805000 ) { // We hit the iris. Do the math. // we start with a ray from the eye to the surface of the eyeball, starting at the surface float3 ray_dir = normalize( v2f.objCoord - objEyePos ); float3 ray_origin = v2f.objCoord; // refract the ray before intersecting with the iris sphere ray_dir = refract( ray_dir, objFlatNormal, g_refraction_u ); // first, see if the refracted ray would leave the eye before hitting the Iris. float t_eyeballSurface = SphereIntersect( 16.0, ray_origin, ray_dir ); // 16 = 4 * 4, we assume the sphere of the eyeball is radius 4 here float3 objPosOnEyeBall = ray_origin + t_eyeballSurface * ray_dir; float3 centerToSurface2 = normalize( objPosOnEyeBall ); if( centerToSurface2.y > 0.805000 ) { // Display a blue color diffuseCol = float3( 0, 0, 0.7 ); objBumpNormal = objFlatNormal; specularCol = float3( 0, 0, 0 ); specExp = 10.0; } else { // transform into irisSphere space ray_origin.y -= 5.109000; // intersect with the Iris sphere float t = SphereIntersect( 9.650000, ray_origin, ray_dir ); float3 SphereSpaceIntersectCoord = ray_origin + t * ray_dir; float3 irisNormal = normalize( -SphereSpaceIntersectCoord );
NVShaderPerf 1.8
Eye Shader from LunaMaximum branch takes 674 cyclesMinimum branch takes 193 cycles.
Copyright © NVIDIA Corporation 2004
NVShaderPerf – version 2.0
Vertex throughputGLSL vertex programMultiple driver versions from one NVShaderPerfMuch smaller footprintNew programmatic interfaceWhat else do you need?
Copyright © NVIDIA Corporation 2004
Questions?
Developer tools DVDs available at our boothNVPerfKit 2.0NVPerfHUD 4.0 MaterialsUser Guides
Online: http://developer.nvidia.com/NVPerfKithttp://developer.nvidia.com/NVPerfHUD
Copyright © NVIDIA Corporation 2004
Copyright © NVIDIA Corporation 2004
NVIDIA SDK
Hundreds of code samples and effects that help you take advantage of the latest in graphics technology.
Tons of updated and all-new DirectX and OpenGL code samples with full source code and helpful whitepapers:
Transparency AA, GPU Cloth, Geometry Instancing, Rainbow Fogbow, 2xFP16 HRD, Perspective Shadow Maps, Texture Atlas Utility, ...
Hundreds of effects, complete with custom geometry, animation and more:
Shadows, PCSS, Skin, Plastics, Flame/Fire, Glow, Image Filters, HLSL Debugging Techniques,Texture BRDFs, Texture Displacements, HDR Tonemapping, and even a simple Ray Tracer!
The Source for GPU Programming
Copyright © NVIDIA Corporation 2004
GPU Gems 2 Programming Techniques for High-Performance Graphics and General-Purpose Computation
880 full-color pages330 figuresHard cover$59.99Experts from universities and industry
Geometric Complexity
Shading, Lighting, and Shadows
High-Quality Rendering
General Purpose Computation on GPUs: A Primer
Image-Oriented Computing
Simulation and Numerical Algorithms
Graphics ProgrammingGraphics Programming GPGPU ProgrammingGPGPU Programming