glBeginQuery/glEndQuery/glQueryCounter获取GPU执行指令耗时

GLES3.0中文API-glBeginQuery 名称 glBeginQuery — 划定查询对象的边界 C规格 void glBeginQuery( GLenum target, GLuint id); void glEndQuery( GLenum target); 参数 glBeginQuery target 指定在glBeginQuery和后续glEndQuery之间建立的查询对象的目标类型。 符号常量必须是GL_ANY_SAMPLES... 阅读详情

Timer Queries

         One further query type that you can use to judge how long rendering is taking is the timer query. Timer queries are made by passing the GL_TIME_ELAPSED query type as the target parameter of glBeginQuery() and glEndQuery(). When you call glGetQueryObjectuiv() to get the result from the query object, the value is the number of nanoseconds that elapsed between when OpenGL executes your calls to glBeginQuery() and glEndQuery(). This is actually the amount of time it took OpenGL to process all the commands between the glBeginQuery() and glEndQuery() commands. You can use this, for example, to identify the most expensive part of your scene. Consider the code shown in Listing 12.8.

          另一个查询类型就是timer query,你可以用这个技术来查询渲染花费了多少时间。当我们使用timer query的时候,传给glBeginQuery和glEndQuery的参数要相应的变成GL_TIME_ELAPSED。当你调用glGetQueryObjectuiv获取 query object的结果的时候,返回值是从你调用glBeginQuery开始到你调用glEndQuery之间所有的OpenGL指令耗费的时间,单位是纳秒。你可以通过这个数据来评估你场景中渲染最耗时的部分。我们来看看清单12.8的代码:

// Declare our variables
GLuint queries[3]; // Three query objects that we'll use
GLuint world_time; // Time taken to draw the world
GLuint objects_time; // Time taken to draw objects in the world
GLuint HUD_time; // Time to draw the HUD and other UI elements
// Create three query objects
glGenQueries(3, queries);
// Start the first query
glBeginQuery(GL_TIME_ELAPSED, queries[0]);
// Render the world
RenderWorld();
// Stop the first query and start the second...
// Note, we're not reading the value from the query yet
glEndQuery(GL_TIME_ELAPSED);
glBeginQuery(GL_TIME_ELAPSED, queries[1]);
// Render the objects in the world
RenderObjects();
// Stop the second query and start the third
glEndQuery(GL_TIME_ELAPSED);
glBeginQuery(GL_TIME_ELAPSED, queries[2]);
// Render the HUD
RenderHUD();
// Stop the last query
glEndQuery(GL_TIME_ELAPSED);
// Now we can retrieve the results from the three queries
glGetQueryObjectuiv(queries[0], GL_QUERY_RESULT, &world_time);
glGetQueryObjectuiv(queries[1], GL_QUERY_RESULT, &objects_time);
glGetQueryObjectuiv(queries[2], GL_QUERY_RESULT, &HUD_time);// Done. world_time, objects_time, and hud_time contain the values we want.
// Clean up after ourselves.
glDeleteQueries(3, queries);

Listing 12.8: Timing operations using timer queries

          After this code is executed, world_time, objects_time, and HUD_time will contain the number of nanoseconds it took to render the world, all the objects in the world, and the heads-up display (HUD), respectively. You can use this to determine what fraction of the graphics hardware’s time is taken up rendering each of the elements of your scene. This is useful for profiling your code during development—you can figure out what the most expensive parts of your application are and determine where to spend your optimization effort. You can also use this technique during runtime to alter the behavior of your application and get the best possible performance out of the graphics subsystem. For example, you could increase or reduce the number of objects in the scene depending on the relative value of objects_time. You could also dynamically switch between more or less complex shaders for elements of the scene based on the power of the graphics hardware. If you just want to know how much time passes, according to OpenGL, between two actions that your program takes, you can use glQueryCounter(), whose prototype is

        当这些代码执行完毕之后,world_time,objects_time和HUD_time这三个变量就分别存储着渲染world,所有的objects和HUD所耗费的时间。你可以通过这些信息来确定你渲染的那些元素的开销占比。这对于你在开发的时候去调试 代码的性能是非常有帮助的-你可以通过这样的方式去找到你的代码中最耗时的部分,以便于让你能够知道在哪些地方需要进行优化。举个例子,你可以通过object_time来决定是否需要在你的场景中增加或者减少物体。你可以基于 应用程序运行时所使用的图形硬件来决定使用更复杂的shader还是更简单的shader来渲染物体。如果你仅仅是希望知道OpenGL的某两个操作之间经过了多少时间,你可以使用glQueryCounter函数来查询,它的函数申明如下:

void glQueryCounter(GLuint id, GLenum target);

       You need to set id to GL_TIMESTAMP and target to the name of a query object that you’ve created earlier. This function puts the query straight into the OpenGL pipeline, and when that query reaches the end of the pipeline, OpenGL records its view of the current time into the query object. The time 0 is not really defined—it just indicates some unspecified time in the past. To use this information effectively, your application needs to take deltas between multiple timestamps. To implement the previous example using glQueryCounter(), we could write code as shown in Listing 12.9.

       你需要设置id参数为GL_TIMESTAMP,然后把target参数设置成为你之前创建的query object。这个函数会直接把查询操作推送进OpenGL的流水线中去,当OpenGL执行到那个query object的结束位置的时候,OpenGL会把当前的 时间写到query object里面去。时间0不一定真的存在-这个时间仅仅是表示经过了不确定的一些时间。为了更加有效的使用这个数据,你的程序需要计算多个时间戳的差。清单12.9展示了如何使用glQueryCounter来实现之前的那个 案例的代码。

// Declare our variables
GLuint queries[4]; // Now we need four query objects
GLuint start_time; // The start time of the application
GLuint world_time; // Time taken to draw the world
GLuint objects_time; // Time taken to draw objects in the world
GLuint HUD_time; // Time to draw the HUD and other UI elements
// Create four query objects
glGenQueries(4, queries);// Get the start time
glQueryCounter(GL_TIMESTAMP, queries[0]);
// Render the world
RenderWorld();
// Get the time after RenderWorld is done
glQueryCounter(GL_TIMESTAMP, queries[1]);
// Render the objects in the world
RenderObjects();
// Get the time after RenderObjects is done
glQueryCounter(GL_TIMESTAMP, queries[2]);
// Render the HUD
RenderHUD();
// Get the time after everything is done
glQueryCounter(GL_TIMESTAMP, queries[3]);
// Get the result from the three queries, and subtract them to find deltas
glGetQueryObjectuiv(queries[0], GL_QUERY_RESULT, &start_time);
glGetQueryObjectuiv(queries[1], GL_QUERY_RESULT, &world_time);
glGetQueryObjectuiv(queries[2], GL_QUERY_RESULT, &objects_time);
glGetQueryObjectuiv(queries[3], GL_QUERY_RESULT, &HUD_time);
HUD_time -= objects_time;
objects_time -= world_time;
world_time -= start_time;
// Done. world_time, objects_time, and hud_time contain the values we want.
// Clean up after ourselves.
glDeleteQueries(4, queries);

 

Listing 12.9: Timing operations using glQueryCounter()

          As you can see, the code in this example is not dramatically different from that in Listing 12.8. You need to create four query objects instead of three, and you need to subtract out the results at the end to find the time deltas. However, you don’t need to call glBeginQuery() and glEndQuery() in pairs, which means that there are fewer calls to OpenGL in total. The results of the two samples aren’t quite equivalent, however. When you issue a GL_TIMESTAMP query, the time is written when the query reaches the end of the OpenGL pipeline. However, when you issue a GL_TIME_ELAPSED query, internally OpenGL will take a timestamp when glBeginQuery() reaches the start of the pipeline and again when glEndQuery() reaches the end of the pipeline, and then subtract the two. Clearly, the results won’t be quite the same. Nevertheless, so long as you are consistent in which method you use, your results should still be meaningful.

       如同你所见到的,这份代码跟清单12.8所给出的代码并不是说有特别大的差异。你需要在这里创建4个query object而不是之前的3个,并且你需要计算出来时间差。但是,你不需要成对的去调用glBeginQuery和glEndQuery。 意思就是说,总体来说OpenGL的API调用的数量变少了,只不过这两个例子的结果并不完全等同。当你使用GL_TIMESTAMP的方式进行查询的时候,当OpenGL流水线执行到了query object结束位置的时候,time变量才会被写入数值。 而当你使用GL_TIME_ELAPSED查询方式的时候,OpenGL会计算出来glEndQuery指令执行结束时候的时间戳与glBeginQuery执行指令开始时的时间戳的时间差。很明显,结果不会时一样的。无论你采用哪种方式,你拿到的那个时间数据 都是有意义的。

         One important thing to note about the results of timer queries is that, because they are measured in nanoseconds, their values can get very large in a small amount of time. A single, unsigned 32-bit value can count as a little over 4 seconds’ worth of nanoseconds. If you expect to time operations that take longer than this (ideally over the course of many frames!), you might want to consider retrieving the full 64-bit results that query objects keep internally. To do this, call

        关于timer queries的一个值得注意的事就是,由于它们的计量单位是纳秒,所以它们的数值可能会非常大。如果用一个无符号的32位整数来表示纳秒数据的话,那么它顶多能玩转4秒。所以如果你的某个操作出乎预料的执行时间 超过了4秒,那么你就完蛋了。所以你应该使用64位的整数来获取和存储query object的数据。我们可以通过下面的API来实现这一操作。

void glGetQueryObjectui64v(GLuint id,GLenum pname,GLuint64 * params);

       Just as with glGetQueryObjectuiv(), id is the name of the query object whose value you want to retrieve and pname can be GL_QUERY_RESULT or GL_QUERY_RESULT_AVAILABLE to retrieve the result of the query or just an indication of whether it’s available, respectively. Finally, although not techically a query, you can get an instantaneous, synchronous timestamp from OpenGL by calling

        就像是glGetQueeryObjectuiv函数一样,id是query object的名字,pname参数要么是GL_QUERY_RESULT要么是GL_QUERY_RESULT_AVAILABLE,前者表示获取查询结果,后者用来询问这个结果是否可被查询。最后,还有一个 API,尽管技术上,跟query没啥关系,你可以从OpenGL通过这个API来立即采用同步的方式获取一个时间戳。

GLint64 t;
void glGetInteger64v(GL_TIMESTAMP, &t);

       After this code has executed, t will contain the current time as OpenGL sees it. If you take this timestamp and then immediately launch a timestamp query, you can retrieve the result of the timestamp query and subtract t from it; the result will be the amount of time that it took the query to reach the end of the pipeline. This is known as the latency of the pipeline and is approximately equal to the amount of time that will pass between your application issuing a command and OpenGL fully executing it.

      当这代码执行完毕后,t将会保存OpenGL返回的一个当前的时间。如果你先获取这个时间戳,然后立刻直接执行一个时间戳的查询,获得时间戳查询的结果后用它减掉t;这个结果将是OpenGL执行到查询操作结束位置时所花费的 时间。这也就是我们所知道的OpenGL流水线的延迟,这个延迟基本上等同于从你的应用程序调用某个指令开始,到OpenGL完全执行完毕这个指令的时间。

本文转自:OpenGL-Timer Queries - 知乎 (zhihu.com) 

Renderdoc源码研究——duration计算过程 文章目录源码逻辑Timer Queries 小结1、要了解的是什么?2、为什么需要了解?3、了解的方式是?踩的坑 源码逻辑 1、点击面板上的图标,触发事件 on_timeDraws_clicked() GPUCounter 这个结构体中会存储很多变量,其中的EventGPUDuration 变量就是存放的duration的值。 【定义】GPUCounter:: EventGPUDuration —— 用于表示:此事件在 GPU 上花费的时间,由两个 GPU 时间戳之间的增量衡量。 // Event 阅读详情

相关推荐

3A之自动对焦(AF)算法:从Tenegrad到拉普拉斯的清晰度评价实战

本文深入解析自动对焦(AF)算法的核心——清晰度评价函数,通过实战对比Tenegrad、方差、能量梯度、Brenner和拉普拉斯五大经典算法的原理、代码实现与性能。文章详细阐述了各函数在计算速度、抗噪性和单峰性上的优劣,并提供了从仿真测试到硬件部署的优化策略,帮助开发者根据实际场景选择最合适的AF算法。

weixin_29281915的博客 313

【OpenGL】蓝宝书第十二章——高级几何图形管理

查询功能——收集OpenGL管线相关信息 GPU查询对象是否被绘制在可视范围内 准备查询 void glGenQueries(GLsizei n, GLuint *ids); 创建查询对象(或查询对象数组)n为个数,ids是查询对象指针。 GLuint one_query; GLuint ten_queries[10]; glGenQueries(1, &one_query); glGenQueries(10, ten_queries); 若创建失败内容将是0,可安全校验是否创建成功

两水先木示的博客 1720

别再死记硬背了!用Python可视化带你直观理解柯西收敛定理(附NumPy代码)

本文通过Python可视化技术,结合NumPy和Matplotlib,直观展示柯西收敛定理的动态过程。文章提供了完整的代码实现,帮助读者从抽象数学定义过渡到具象理解,特别适合数学学习者和Python开发者。通过热力图和交互式参数探索,读者可以清晰观察数列收敛特性,提升数学分析的学习效率。

weixin_28465009的博客 185

OpenGL的一些重要函数记录

glViewport — set the viewport https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glViewport.xhtml glQueryCounter — 在所有以前的命令到达GL服务器但还没有执行的情况下,将GL时间记录到查询对象中。 https://www.khronos.org/registry/Open...

weixin_30695195的博客 274

深度解读扫地机器人的导航原理

科技改变生活,不可否认科技的进步的确为我们的生活带来许多便捷,以智能家电为例,智能电饭煲、智能洗碗机、智能扫地机等产品已逐渐成为家庭的一分子,其中以扫地机表现最为抢眼。能做到智能规划清扫,收割了不少家庭主妇及科技爱好者的芳心。但扫地机并非一开始就这么智能,最初的扫地机只能做到随机式清扫,会频繁出现碰撞现象。 近年来,通过业界的不断努力,目前,扫地机器人已告别乱碰乱撞现象,能做到自主路径...

qq_38403231的博客 6504

【项目实战】基于STM32单片机的智能小车设计(有代码)

【1】背景意义 近些年随着国民生活水平的提升,以小车为载体的轮式机器人进入了我们的生活,尤其是在一些布线复杂困难的安全生活区和需要监控的施工作业场合都必须依赖轮式机器人的视频监控技术。因此,基于嵌入式技术的无线通信视频监控轮式机器人应运而生。由于它们与人类工作相比具有成本低廉、安全稳定的优点,目前已经在许多危险作业以及工业场合得到了广泛应用而且轮式机器人不需要像人那样采取过多的保护措施,因此轮式机...

ShawnWang1994的博客 13万+

遮挡查询

遮挡查询步骤 1.为每个遮挡查询对象生成一个ID。glGenQueries(GLsizei n, GLuint * ids); glIsQueries(id); 2.glBeginQuery() ,开始遮挡查询。3.渲染几何体,完成遮挡查询测试。 4.glEndQuery(); 完成查询。5.获取本次通过深度测试的样本数量。** GLuint Query; glGenQueries(1,

皮皮虾图形学 2254

TTL电路搭建半加器实验:操作指南完整版

通过TTL电路搭建半加器,详解逻辑设计与实验步骤,帮助掌握数字电路中的半加器工作原理与实际应用,适合电子技术初学者动手实践。

weixin_42524864的博客 355

Dx12 occlusion query

https://github.com/Microsoft/DirectX-Graphics-Samples/blob/master/Samples/Desktop/D3D12PredicationQueries/src/D3D12PredicationQueries.cpp dx12 de oc query 用了新的 predication https://docs.microso...

anfu8346的博客 331

华北理工大学以升实验班蓝桥杯选拔赛题解

文章目录华北理工大学以升实验班蓝桥杯选拔赛题解A:期末考试题目描述题目讲解代码B:月份题目描述题目讲解代码C:打饭题目描述题目讲解代码D : 正弦波信号题目描述题目讲解代码E : 亲爱的长方形题目描述题目讲解代码F:挖金子题目描述题目讲解代码G : 金金的游戏题目描述题目讲解代码H : 区间和题目描述题目讲解代码详细视频讲解请关注华北理工大学b站账号。 华北理工大学以升实验班蓝桥杯选拔赛题解 A:期末考试 题目描述 Description 期末考试过去许多天了,如今成绩都出来了,那么现在让我们对成绩我分个类

Qq1739206233的博客 1128

C++程序无法正常启动(报0xc000007b错误)问题的详细排查

本文详细介绍了应用程序启动时遇到0xC000007B错误的排查过程。问题源于32位程序与64位运行时库的不匹配,以及缺少依赖的运行时库。通过分析系统日志、使用Windbg和检查程序位数,最终确定问题在于32位程序误引用了64位系统目录下的库文件。

dvlinker的技术专栏 1万+

游戏会记录某个api的调用_(转)游戏画面卡顿问题的检测与解决对策

Cem Cebenoyan NVIDIA开发者技术总监 画面卡顿 – 游戏体验的杀手 当别人问你: “游戏每隔几秒就卡一下…” “测出来的帧数很高, 但总是觉得不流畅…” “感觉人物动画一顿一顿的…” “有时输入延迟很严重…” …… 你知道这是卡顿的问题, 可是 哪儿出错了? 严重损害游戏体验 难以查出卡顿的根源,更加难以排除 在本讲座中, 我们将讨论: 游戏图形渲染中最常见的卡顿现象 鉴别卡...

weixin_39956182的博客 1125

【2026年华为暑期实习(AI)-4月29日-第一题- 选择题】(题目+思路+Java&C++&Python解析+在线测试)

本文摘要涵盖了机器学习和深度学习中的多个核心概念与技术,包括非负矩阵分解、条件数、MobileNet创新点、LDA降维、大模型评测指标、半精度训练、多任务学习、GPU存储层次、正则化、张量并行等。通过12道单选题和8道多选题的形式,系统性地考察了相关理论原理、应用场景及工程实践要点。题目设计注重概念准确性(如LDA目标函数)、技术细节(如Megatron-LM的并行策略)与实际应用(如FP16训练动机),并包含概率统计(二项分布)和数值计算(微分误差分析)等数学基础内容,全面检验读者对AI领域关键知识的掌握

m0_73659489的博客 143

GLES3.0中文API-glGenQueries

名称 glGenQueries —生成查询对象名称 C规范 void glGenQueries(GLsizei n, GLuint * ids); 参数 n 指定要生成的查询对象名称的数量。 ids 指定用于存储生成的查询对象名称的数组。 描述 glGenQueries返回ID中的n个查询对象名称。 不能保证名称形成连续的整数集。 但是,可以保证在调用glGenQueries之前,不会立即使用任...

MSK1111的博客 846

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

OpenGL查询对象 Query Objects

查询对象和异步查询(Query Objects and Asynchronous Queries)

1621

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

opengl基础

opengl基础异步和同步 异步和同步 通常来讲,opengl规范规定了opengl指令需要按给定的顺序执行,但这只是规范的行为,具体执行时不一定是这么做的 opengl渲染指令是异步执行的,例如调用了一系列glDraw*指令,调用返回时渲染指令未必结束执行(有可能还没开始执行…),它会将一系列指令打包发送到GPU执行,因此不能直接通过测cpu返回耗时去测gpu渲染耗时(一种可以尝试的办法是使用glFinish,glFinish会立即发送命令到GPU并等待执行结束,测试耗时时要注意clock和steady

LilyZJ的博客 828

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

关于切换场景加载耗时的优化问题

UWA一下,你就知道~

UWA—简单优化,优化简单! 1038

《高效学习OpenGL》 之 深度测试 遮挡查询 glDepthFunc(), glGenQueries(), glBeginQuery(), glGetQueryObjectiv()

1.为深度测试设置比较函数: glDepthFunc(GLenum func); //func默认为GL_LESS 2.遮挡查询 生成一组未使用的查询ID: glGenQueries(GLsizei n, GLuint *ids); //返回n个当前未使用的ID,可用于表示遮挡对象的名称。这些名称是在ids数组中返回的。 判断一个标识符当前是否被一个遮挡查询

编辑编辑器 6151

原创 【我的OpenGL学习进阶之旅】介绍一下OpenGL ES的 遮挡查询

目录一、遮挡查询1.1 开始和结束遮挡查询1.2 创建和删除id1.3 检索查询对象的结果1.4 遮挡查询的步骤1.5 例子1.5 扩展阅读 一、遮挡查询 在一个场景中,如果有有些物体被其他物体遮住了不可见。那么我们就不需要绘制它。 在复杂的场景中,这可以减少大量的顶点和像素的处理,大幅度的提高帧率。 遮挡查询就是允许我们判断一组图形在进行了深度测试之后是否可见。 遮挡查询可用于查询对象来跟踪通过深度测试的任何片段或者样本。 这种方法可用于不同的技术,例如镜头炫光特效的可见性测试以及避免在包围体被遮挡的不

字节卷动 1937

游戏优化常见技巧(OpenGL)

OpenGL渲染优化:优化性能的主导思想是:流水线的速度由最慢的一个阶段决定; OpenGL基本优化: 减少OpenGL的状态变化; 每当我们改变一个OpenGL状态,可能会涉及到硬件的多个寄存器的数据,那么驱动程序就必须将修改的硬件寄存器通过AGP总线发送到硬件,占用大量的CPU资源和AGP带宽和硬件命令解释器时间; Advice1:尽可能将状态相近的图形绘制命令放在一起,减少Ope...

Tokyo_2024的博客 6110

GLES3.0中文API-glGetQueryObjectuiv

名称 glGetQueryObjectuiv — 返回查询对象的参数 C规格 void glGetQueryObjectuiv( GLuint id, GLenum pname, GLuint * params); 参数 id 指定查询对象的名称。 pname 指定查询对象参数的符号名称。可接受的值为GL_QUERY_RESULT或GL_QUERY_RESULT_AVAILABLE。 para...

MSK1111的博客 1017

计算程序运行时间

计算程序运行时间 方法一: int64 now,then; double elapsed_seconds, tickspersecond=cvGetTickFrequency() * 1.0e6;  while(1) {  then = cvGetTickCount();  doSomeStuff();  now = cvGetTickCount();  elaps

GL_a_的博客 530

OpenGL超级宝典(第7版)之第十二章管线监控

OpenGL超级宝典(第7版)之第十二章管线监控前言一、查询1.遮挡查询二、OpenGL同步 前言 查询命令在图形管线中的执行进程 测量命令执行时间 同步应用程序与OpenGL以及同步多重OpenGL语境 一、查询 简述:查询Opengl执行状态需要创建查询对象,一个对象查一个问题,查询完一个问题必须删除一个查询对象 glGenQueries():生成查询对象 glDeleteQueries():删除查询对象 glGetError():查询上面函数执行的结果 1.遮挡查询 简述:用于对于渲染成本很高的,但

Jason_Chen__的博客 567
上一篇: osgGA::CameraManipulator类computeHomePosition函数分析
下一篇: 浅谈osgViewer::StatsHandler、osg::Stats类的用法
荆楚闲人
博客等级 码龄20年 3万+粉丝 473原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值