首页 > 其他分享 >高通个别驱动创建Buffer耗时高问题的解决

高通个别驱动创建Buffer耗时高问题的解决

时间:2023-07-12 13:56:02浏览次数:42  
标签:开销 耗时 Buffer 创建 高通 buffer GL

前言

最近在优化游戏的时候,发现在在高通特定驱动版本的机器上(855,855+等),创建VB的耗时跟VB的数量成正比,这个应该是驱动的bug。跟官方人员确认过,确实是有这个问题,他们给的解决方案是减少Buffer的数量,经过一轮优化后,Buffer数量减少了将近30%,但是这个耗时的问题还是没能解决,在正常机型上创建100个VB的开销大约在几ms的时间,但是在有问题的机器上可以达到30多ms。那这个问题有没有可能解决呢?是有方法的,这里也把解决过程记录下,给遇到相关问题的人做个参考。

解决方案

尝试1

首先想到的是像内存管理一样预创建特定大小的Buffer,在后面所有使用到的地方直接从Pool里面去取,然后调用glBufferSubData去更新,这个时候Buffer的创建开销确实大缩短了,在framepro中基本上看不到Buffer创建的耗时,但是耗时开销转移了!转移到了创建纹理相关的操作上!!!而且耗时跟你预创建Buffer的数量成正比。

 

                                           创建VB开销小了很多

 

                                            创建纹理开销显著增加

那这个方案看起来是行不通的。

尝试2

既然是跟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执行完成。

一些处理细节:

  1. 因为Index Buffer相关的接口不是所有的都支持offset,所以Index buffer走预创建Buffer的方式。
  2. Shader里面会访问texture buffer,这个时候需要使用offset来做,为了减少Shader的修改,我们这部分数据也采用预创建buffer的方式来处理。

优化效果

优化前:

 

 

优化后:

 

 

可以看到优化前有很多峰值,优化后基本上看不到创建Buffer的开销,创建纹理的开销也正常。

总结

因为我们是大世界游戏,所以Buffer数量比较多,容易触发这个问题。不知道有没有人遇到这个问题,以及你们是如何解决的,欢迎一起讨论,解决的方式比较Trick,这里就把它记录下来。

参考

  1. https://registry.khronos.org/OpenGL-Refpages/es3.0/html/glMapBufferRange.xhtml

 

标签:开销,耗时,Buffer,创建,高通,buffer,GL
From: https://www.cnblogs.com/ghl_carmack/p/17547290.html

相关文章

  • mybatisPlus 中设置批量更新执行耗时
    设置myBatisPlus中使用批量更新执行的时间耗时短在连接mysql的url后添加&rewriteBatchedStatements=true为什么默认不给这个rewriteBatchedStatements属性设置为true,原来有如下原因:看下executeBatchedInserts究竟干了什么:如果批量语句中的某些语句失败,则默认重......
  • (2023.7.11)usb: ring buffer full
    现象:在对usb接口的5G模组灌包时出现异常打印,xhci-hcdxhci-hcd.0.auto:ERRORunkown eventtype37/USBGadgetDriver定义了很多traceevent,使用者可以在用户空间通过ftrace接口,追踪USBGadgetDriver的行为;/用户空间接口路径为/sys/kernel/debug/tracing/events/dwc3:包含了......
  • 【音频频率筛选电路LTSpice仿真模型】 涉及到高通低
    【音频频率筛选电路LTSpice仿真模型】涉及到高通低通Sallen-Key滤波器,DABP滤波器,具有较高的参考价值ID:3168654721676077......
  • String、StringBuffer、StringBuilder 的区别?
    一.介绍String、StringBuffer、StringBuilder:  前言: String、StringBuffer、StringBuilder均在java.lang包下;String: 在Java中,String是一个特殊的引用类型,用于表示文本字符串。它提供了许多方法来操作和处理字符串,比如连接、截取、查找、替换等。String类......
  • 北京至达教育咨询有限公司:高通过率背后的卓越教育力量
    2019年应急管理部和人社部随即协同颁布了《注册安全工程师职业资格制度规定》和《注册安全工程师职业资格考试实施办法》,对注安各项管理章程都作出了明确的规范,进一步提升和巩固了注册安全工程师的社会地位,这一切都预示着注安工程师在2019真的迎来了新的风口。至达教育,前身作为......
  • 页面显示查询耗时
    执行耗时接口,页面显示计时器lettt=document.querySelector('.spanTimer')asHTMLElement;letnum=0;tt.innerText=num+'秒';letmin='';letsec='';lettimeOut=setInterval(function(){//开启定时器num++;if(num<......
  • 【项目实战功能】自定义注解实现代码的执行耗时记录
    博主介绍:✌博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家,阿里云专家博主,华为云云享专家✌......
  • 分布式ID|从源码角度深度解析美团Leaf双Buffer优化方案
    分布式ID的使用场景基于MySql的初步方案第一次优化:Leaf-segment数据库方案第二次优化:Leaf-segment双buffer优化源码解析双buffer优化方案 背景 在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识。如在美团点评的金融、支付、餐饮、酒店、猫眼电影等产......
  • Java中使用BufferedReader类来读取大文本文件
    importjava.io.BufferedReader;importjava.io.File;importjava.io.FileReader;importjava.io.IOException;publicclassReadLargeTextFile{publicstaticvoidmain(String[]args){Filefile=newFile("large_file.txt");try......
  • Java中NIO为什么需要buffer
    在Java的NIO(NewInput/Output)中,Buffer是一个关键概念,用于高效地处理数据。以下是一些JavaNIO中需要Buffer的原因:内存管理:Buffer提供了一种更有效的内存管理方式。它可以在堆内存或直接内存中创建一个固定大小的内存区域,用于暂存数据。这样可以避免频繁的内存分配和释放操作,提......