异步上传管线AUP答疑

2023-10-30 19:10
文章标签 异步 上传 答疑 管线 aup

本文主要是介绍异步上传管线AUP答疑,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这是第171篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间20分钟,认真读完必有收获。

UWA 问答社区:answer.uwa4d.com
UWA QQ群2:793972859(原群已满员)


本期目录:

  • 异步上传管线AUP答疑
  • PSS的优化方法
  • 2017.3 iOS运行内存过高
  • PhysicMaterial中的bounciness问题
  • UGUI相同材质合批后如何确认UI元素的遮挡关系

加载

Q:对AUP产生疑问,主要目的是想知道是否已经适合在现在的项目里使用了?

目前项目里大部分用的是同步加载,所以应该全部改成异步加载吗?博客里的意思是AUP可以在渲染线程做加载,那如何保证渲染线程不会卡主线程呢?我们使用2018.4版本,如果加载一个角色,除了Texture、Mesh之外,其它的资源还是会走正常的同步加载?这种相对复杂的Prefab加载适合用异步吗?

A1:AUP跟同步/异步加载没关系,只是Texture跟Mesh的加载放到了渲染线程。我这里也是同步加载的,从真机上看到同步记载Texture和Mesh也是走渲染线程。同步加载的时候,不会卡主线程的,这点跟UWA的技术人员确认了。在加载界面的时候,我调大了时间切片耗时。判断机子内存多,加大了加载内存。有一点不明白的是,当Loading界面同步加载非常多的情况下,例如:一帧耗时500多毫秒,相对应的时间切片耗时可以跑到100ms耗时。
感谢剑影蒙残@UWA问答社区提供了回答

A2:回答第一个问题:

正如@剑影蒙残 所说,AUP和加载API的同步加载还是异步加载没有关系。当AUP功能和多线程渲染功能开启后,无论是Load还是LoadAsync,Texture和Mesh资源都是在加载线程加载好后,从渲染线程提交到GPU的。而在没有AUP功能时,这两项资源的GPU Upload都是在主线程完成。这样的好处显而易见,就是将主线程的卡住时间转移到渲染线程进行完成,从而让主线程可以处理更多逻辑事物。

需要注意的是,在2018.3及以后版本中,AUP才支持Texture和Mesh,在2018.2版本中,AUP只支持Texture资源。

回答第二个问题:

确实,当有大量Texture或者Mesh资源需要传输时,渲染线程很可能是吃不消的,但需要考虑加载的时间点,如果是在场景切换时加载,且允许可以存在一定的画面卡住需求,那么可以尝试通过Load API来进行加载;反之,在战斗过程中或者需要平滑加载时,则使用LoadAsync API。二者的最主要区别是在于加载的资源量要不要在下一帧结束前完成。如果需要,则使用Load,Texture和Mesh虽然在渲染线程进行Upload,但一定要在下一帧结束前完成,这样就很有可能会造成主线程的等待,但相较于以前Unity版本,其优点是主线程依然可以执行其它耗时计算,比如UnloadUnusedAssets、配置文件的加载等。

而如果想要尽可能平滑,则Unity引擎提供了AsyncUploadTimeSlice和AsyncUploadBuffer两个参数,虽然在之前的Unity版本中也这两个参数,但经过大量测试下来,并无法像2018.2之后容易控制。

这两个参数一个控制每帧中的Upload最大时间,一个控制每帧中允许Upload的最大数据量,两者相辅相成,控制AUP在每帧中的加载耗时。所以,我们在UWA DAY 2019中也对这两个数值的使用进行了详细说明,如下图所示:

 

 

当渲染线程压力较大时,可尽可能控制上述两个参数来降低渲染线程由Upload数据而造成卡住主线程的概率。

回答第三个问题:

其实目前加载一个角色Prefab时,已经可以有很多资源都可以通过异步加载来进行,直接通过异步加载接口调用即可,这个跟AUP就是另外的问题了。AUP指的是Texture和Mesh在提交到GPU时的异步提交操作,其本质是在资源加载之后进行的,也就是说和异步加载是两回事。

相对复杂的Prefab确实适合来做异步加载,我们曾经在今年UWA DAY上做了一个非常重的UI界面加载测试,如果按照默认设置进行同步和异步加载,则耗时分别为:293ms和851ms,小米Mix2设备上。

 

 

而在经过了调整加载策略后,其异步加载耗时可以将为313ms,和同步加载相差很小,但好处是主线程留下来大量的时间来处理其它逻辑操作,且很平滑。

 

对于UI Prefab如此,对于角色Prefab亦如此。在优化2018.2以后的异步加载时,需要更多考虑如何控制资源在异步加载之后,在主线程的“后加载”耗时。比如,各种资源的AwakeFromLoad和Shader.Parse等操作。对此,我们在《Unity引擎加载模块和内存管理的量化分析及优化方法》进行了详细的分享,有兴趣的朋友前往观看。

该回答由UWA提供,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5d4cf328c494b506d267391e


PSS

Q:vivo、OPPO机型统计的PSS相比于其它厂商要高,有没有相应的解释文章,或者针对这类机型优化的办法?

A:不同手机厂商或者说相同厂商不同的机型,其PSS统计是会有差异的,主要还是其系统管理策略不同。楼主如果觉得某一机型PSS高,那么可以拿它与其它机型的PSS各个模块进行对比,看看有什么模块较为明显异常。

一般来说,你只要优化你的资源和代码使用,即可降低PSS的占用。比如,在华为mate8上EGL Mtrack和GL Mtrack加起来就是你的Graphics大小,EGL Mtrack一般是OpenGL驱动层的一些Buffer的占用,一般只要你降低分辨率或者说编辑器设置不勾选use32BitDisplayBuffer选项,都能减少EGL Mtrack的占用;GL Mtrack则是纹理网格等一些内容的占用。

当然PSS最大的占用可能还是Native的占用,尽量减少你的Object数量,优化你的Mono内存,减少你的Shader占用,这些都能优化PSS。

感谢李星@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5d4819be27d7e5590f6cd8c5


内存

Q:Unity 2017.3版本iOS打出空包时运行内存达到了80MB,项目是2D卡牌类型。

项目在打包Android APK运行时很流畅,但是在iOS上问题比较严重,检查了,图集资源占用比较高。所以对一些图片资源进行了减低分辨率的操作,并且把相机的HDR MSAA一并去除。

QualitySettings也进行了一些配置,项目中没用到阴影,所以把与阴影相关的该关的关、该降低的降低。

 

 

但是发现还是没有改变。

新建一个空工程,只有一个场景,一个脚本控制按钮可点击。用Memory Profile测试过后,编辑器中占用内存在50MB左右。

Render Texture

 

 

 

但是打包到iOS中调试,在场景刚开始加载的时候瞬间就达到了80MB,XCode中查看不了具体的方法名字,只能查看到内存地址。

所以想请教一下,这个空包如何减少内存初始分配占用?是什么占用掉的内存?

A:这个问题Unity已经关闭掉了。原因是在iOS 12和Xcode 10上,Apple的内存报告工具已经更新,以便更准确地跟踪现有版本之前的内存占用。换句话说,并不是因为应用程序消耗更多内存,而是之前报告的内存不足。仅当针对iOS12构建应用程序时,才会观察到此行为,并且不适用于针对iOS11构建的现有应用程序。在使用XCode 10升级应用程序后,将只会观察到这些更改。对于使用Metal的游戏尤其如此,因为大多数分配都发生在内核空间中,而以前并未考虑应用程序的内存占用。

附上iOS对此的解释:https://developer.apple.com/documentation/metal/reducing_the_memory_footprint_of_metal_apps

感谢题主刘逸宸@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5d4bbd27c494b506d26738f5


物理

Q:多年前偶然发现,当PhysicMaterial中的弹性bounciness设置为1时,在Unity默认的物理作用下,它在一个同样材质的地面上,会越弹越高,理论上不是应该在同一个高度一直弹下去吗?最近因为工程需要,发现这个问题还没有解决,我想问下各位大神,这是Unity的问题还是我的操作不对?应该怎么解决呢?

 

物理材质设置

 

小球设置

 

地面设置

 

 

A:我尝试按照题主的方式,在Unity 5.6.4p4上完美可以复现这种状况,就感觉很有意思。

解决这个问题倒是简单,题主现在的问题就是莫名其妙地获得了动能。只需要我们固定住动能就可以了。或者说,直接不用自带的运动表现,自己去计算这些东西也可以。

比如:

var firstTimeVelocitySave = false;
var savedVelocity = Vector3.zero;
void  OnCollisionEnter(Collision col ) 
{if (! firstTimeVelocitySave) {savedVelocity = rigidbody.velocity;firstTimeVelocitySave = true;}myRigidbody.velocity.y = savedVelocity.y;
}

或者:

rigidbody.velocity = new Vector3(collision.relativeVelocity.x,collision.relativeVelocity.y);

或者:

rigidbody.velocity = Vector3.Reflect(rigidbody.velocity, normal);

或者直接使用添加力的方式自行计算都可以。

找了一些相关资料,发现这个东西在不同版本的Unity上表现还不一致。

在Unity 4.x上,将系数设置成0.9699999;

在Unity 5.x上将系数设置成0.9805824可以得到一个相对完美的碰撞小球。

这2个系数来源于:https://answers.unity.com/questions/736091/how-to-get-a-perfect-bouncing-ball.html

在我本机上的版本4.3.2f、4.6.1f、5.2.6f、5.6.5p4都可以得到预期结果。

另外下面有答主说设置成Collision Detection可以解决这个问题,查询了文档:

Collision Detection How collisions with other objects are detected. Discrete A collision is registered only if the object’s collider is in contact with another during a physics update. Continuous A collision is registered if the object’s collider appears to have contacted another between updates.

一个不成熟的猜测是,连续碰撞可以在撞击的有效时间解决碰撞,而离散碰撞在物体已经重叠的帧时间解析。然后,离散碰撞计算的时间不准确性可能会给系统增加能量。另外,这个东西是不是与浮点数计算有关还不确定。

感谢洋葱小同学@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5d45357727d7e5590f6cd850


UI

Q:查看UGUI合批的原理时看到相同Depth,相同材质的元素会合批。如下图所示,4个image会合并为一个Mesh,我的问题是,在1DrawCall的前提下,这4个image的遮挡/先后关系是怎么得到保证的?

 

 

 

 

A:UGUI同一节点层级下,遮挡关系就是节点的先后顺序。如你举例的图片所示,节点顺序分别是0、1、2、3。

UGUI以Canvas为单位重绘,绘制的CanvasElement依次加入到绘制列表中(UGUI自己实现的数据结构IndexedSet)。

列表中元素即为有序的:0、1、2、3。所以发生rebind时候,会依次把0、1、2、3绘制出来,同一层级下后绘制的由于位置关系影响就会被遮挡。

代码可以阅读UGUI源码中关于Canvas绘制相关的内容,主要看注册更新和rebuild的地方就明白了。

感谢私念@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5d491d87f693b15914337aec

封面图来源于网络


今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。

官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
UWA学堂:edu.uwa4d.com
官方技术QQ群:793972859(原群已满员)

这篇关于异步上传管线AUP答疑的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/309987

相关文章

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

Python一次性将指定版本所有包上传PyPI镜像解决方案

《Python一次性将指定版本所有包上传PyPI镜像解决方案》本文主要介绍了一个安全、完整、可离线部署的解决方案,用于一次性准备指定Python版本的所有包,然后导出到内网环境,感兴趣的小伙伴可以跟随... 目录为什么需要这个方案完整解决方案1. 项目目录结构2. 创建智能下载脚本3. 创建包清单生成脚本4

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

SpringBoot实现不同接口指定上传文件大小的具体步骤

《SpringBoot实现不同接口指定上传文件大小的具体步骤》:本文主要介绍在SpringBoot中通过自定义注解、AOP拦截和配置文件实现不同接口上传文件大小限制的方法,强调需设置全局阈值远大于... 目录一  springboot实现不同接口指定文件大小1.1 思路说明1.2 工程启动说明二 具体实施2

Python异步编程之await与asyncio基本用法详解

《Python异步编程之await与asyncio基本用法详解》在Python中,await和asyncio是异步编程的核心工具,用于高效处理I/O密集型任务(如网络请求、文件读写、数据库操作等),接... 目录一、核心概念二、使用场景三、基本用法1. 定义协程2. 运行协程3. 并发执行多个任务四、关键

C#异步编程ConfigureAwait的使用小结

《C#异步编程ConfigureAwait的使用小结》本文介绍了异步编程在GUI和服务器端应用的优势,详细的介绍了async和await的关键作用,通过实例解析了在UI线程正确使用await.Conf... 异步编程是并发的一种形式,它有两大好处:对于面向终端用户的GUI程序,提高了响应能力对于服务器端应

C# async await 异步编程实现机制详解

《C#asyncawait异步编程实现机制详解》async/await是C#5.0引入的语法糖,它基于**状态机(StateMachine)**模式实现,将异步方法转换为编译器生成的状态机类,本... 目录一、async/await 异步编程实现机制1.1 核心概念1.2 编译器转换过程1.3 关键组件解析

如何在Java Spring实现异步执行(详细篇)

《如何在JavaSpring实现异步执行(详细篇)》Spring框架通过@Async、Executor等实现异步执行,提升系统性能与响应速度,支持自定义线程池管理并发,本文给大家介绍如何在Sprin... 目录前言1. 使用 @Async 实现异步执行1.1 启用异步执行支持1.2 创建异步方法1.3 调用

Spring Boot 结合 WxJava 实现文章上传微信公众号草稿箱与群发

《SpringBoot结合WxJava实现文章上传微信公众号草稿箱与群发》本文将详细介绍如何使用SpringBoot框架结合WxJava开发工具包,实现文章上传到微信公众号草稿箱以及群发功能,... 目录一、项目环境准备1.1 开发环境1.2 微信公众号准备二、Spring Boot 项目搭建2.1 创建

GitLab文件的上传与下载方式

《GitLab文件的上传与下载方式》:本文主要介绍GitLab文件的上传与下载方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录GitLab 项目拉取到本地GitLab 项目上传方法方法 1:本地项目未初始化Git方法 2:本地项目已初始化GitGitLab 上