- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
最近在优化游戏的时候,发现在在高通特定驱动版本的机器上(855,855+等),创建VB的耗时跟VB的数量成正比,这个应该是驱动的bug。跟官方人员确认过,确实是有这个问题,他们给的解决方案是减少Buffer的数量,经过一轮优化后,Buffer数量减少了将近30%,但是这个耗时的问题还是没能解决,在正常机型上创建100个VB的开销大约在几ms的时间,但是在有问题的机器上可以达到30多ms。那这个问题有没有可能解决呢?是有方法的,这里也把解决过程记录下,给遇到相关问题的人做个参考.
首先想到的是像内存管理一样预创建特定大小的Buffer,在后面所有使用到的地方直接从Pool里面去取,然后调用glBufferSubData去更新,这个时候Buffer的创建开销确实大缩短了,在framepro中基本上看不到Buffer创建的耗时,但是耗时开销转移了!转移到了创建纹理相关的操作上!!!而且耗时跟你预创建Buffer的数量成正比.
。
创建VB开销小了很多 。
。
创建纹理开销显著增加 。
那这个方案看起来是行不通的.
既然是跟Buffer数量成正比,那就直接减少Buffer数量,尝试像Vulkan、Metal、D3D12来管理内存,思路就是像内存管理一样创建特定大小的大Buffer,然后使用ringbuffer的方式来管理内存,通过glMapBufferRange来局部更新内容.
。
理论上是完全成立的,但是在实际的时候还是有不少小坑需要处理。一开始使用glMapBufferRange ( GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT ) 来更新buffer,但是发现性能出奇的差,不过同样的操作在另外一个联发科的机器上就没有问题,可能跟驱动的实现有关.
。
我们在来看另外一个标记GL_MAP_UNSYNCHRONIZED_BIT,这个标记的意思就是你驱动别做同步了,我自己保证数据的正确性.
GL_MAP_UNSYNCHRONIZED_BIT indicates that the GL should not attempt to synchronize pending operations on the buffer prior to returning from glMapBufferRange. No GL error is generated if pending operations which source or modify the buffer overlap the mapped region, but the result of such previous and any subsequent operations is undefined.
。
看到这个标记感觉应该能跑通了,我们使用这个标记并配合RingBuffer来实现内存的管理,这里为了保证数据准确有两个实现方式,一个是确保RingBuffer足够大,不会出现数据被写的情况,另外一个是加一个Fence来做同步,小于一定数量的时候强制等GPU执行完成.
一些处理细节:
优化前:
。
。
优化后:
。
。
可以看到优化前有很多峰值,优化后基本上看不到创建Buffer的开销,创建纹理的开销也正常.
因为我们是大世界游戏,所以Buffer数量比较多,容易触发这个问题。不知道有没有人遇到这个问题,以及你们是如何解决的,欢迎一起讨论,解决的方式比较Trick,这里就把它记录下来.
。
最后此篇关于高通个别驱动创建Buffer耗时高问题的解决的文章就讲到这里了,如果你想了解更多关于高通个别驱动创建Buffer耗时高问题的解决的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我在我的 UIPath 项目中实现了一个普通的“for each”循环(不是每行特定的 excel)。 for-each 循环使用以前从 excel 文件中检索到的数据查看数据表。 然后,for-ea
我认为我的 SQL 查询花费的时间太长,现在看起来大约需要 30 秒。我有两个表,Record 和 Mainrecord。我想获取有关列金额中包含 0 的所有 Mainrecords 的信息,并且在这
这个编辑器是水平的http://tinymce.moxiecode.com/examples/simple.php我似乎只找到水平编辑器,有人遇到过垂直编辑器吗?有什么例子吗? build 需要多长时
我想创建一个跟踪任务时间的 ASP.NET WinForms 应用程序。我需要能够编写表单,以便将任务添加到数据库、在新选项卡中打开它,以及能够开始、暂停和停止任务。完成后,我需要计算完成任务所需的时
抱歉,我是 C 的新手。但我做错了什么?几乎尝试了一切,但仍然无法计算执行 t1 和 t2 之间的代码所传递的秒数,总是返回我在 0.00 秒内完成。感谢您的耐心等待:) #include cloc
我有 2 个简单的函数(在一个范围内循环)可以单独运行而没有任何依赖性。我正在尝试使用 Python 多处理模块和多线程模块来运行这 2 个函数。 当我比较输出时,我看到多进程应用程序比多线程模块多花
尝试记录使用装饰器运行函数所需的时间,但我误解了一些东西。它拒绝写登录装饰器。 当你颠倒装饰器的顺序时,它会导致模板上的构建错误(就像信息丢失一样)。 在我的初始 py 中: if app.debug
我听说 System.out.println(); Java 语句是昂贵的(它消耗了很多时间) 所以我试着评估一下它的成本: 当我评估 5 个语句时...成本 = 1.0 所以我预计 1 条语句的成本
我正在使用 codeigniter REST-API(作者:philsturgeon 引用 URL: https://github.com/philsturgeon/codeigniter-rests
我在 SFML 中有一个时钟和计时器,它测量秒数。我试图在经过一定秒数(特别是 4 秒)后执行下一个操作 这是我的代码 #include "stdafx.h" #include "Splash
例如,我们在 SomeActivity 中,该 Activity 有一个按钮,用于调用将文件从一个目录移动到另一个目录(我们称之为作业)。 在黑莓手机上我会: 推送一个不可取消的弹出窗口(对话框屏幕)
我正在尝试从大小为 7,140,000 的 ArrayList 中删除 140,000 个对象。我预计这会花费几秒钟(如果那样的话),但 Java 每千个对象花费几秒钟。这是我的代码:
我得到了这个查询,它占用了我的 elapsed_time 并且工作正常,但后来我意识到我得到的 actual_elapsed 的值是错误的。 actual_elapsed 是我使用 TIMEDIFF(
我在更新面板中放置了一个 GridView。 当用户按下按钮时,gridView 将被一个数据表填满: GridView_Overview.Da
客户想要将数据库从 MS SQL 转换为 MySql。 就我个人而言,我不会这样做,我更喜欢使用 MS SQL 来处理大型数据库,并且喜欢使用 MSSQL 时可用的工具。 但是我确实在较小的项目上使用
我目前正在为一个 Julia 项目使用 Graph Database,使用 Redis。 有时 Redis 请求需要 300 毫秒才能执行,我不明白为什么。我运行了一个简单的请求 10.000 次(请
我们在一次运行中处理了 500 万个请求。然而,在运行期间,很少有请求失败。验证关闭后,我们了解到 Full GC 已启动,并且花费了超过 40 秒(到 60 秒),从而导致超时。 配置:我们有 3
我是一名优秀的程序员,十分优秀!