GameDesign 板


LINE

网页版 https://yekdniwue.blogspot.com/2019/06/BunchOverhead.html 这篇文章其实算是Network Profiler (一) (二)的後续, 主要是利用Profiler分析的过程中发现replicate property已经减少很多, 可是total send Bytes没有如预期的下降到目标, 经过追查研究後,发现问题在Bunch Overhead後, 才有了这一篇文章的内容 Bunch Overhead 如果降replicate传输到一定程度之後,会发现其实Bunch Overhead蛮大的。 从Profiler里面可以看到Bunch Overhead分为 ★Bunch Headers ★ContentBlock Headers ★Content Footers ★Handles ★Export GUIDS ★MustBeMapped GUIDS 这几个项目 如图1.所示 [图1.] 图1. BunchOverhead的细项可在Network Profiler的Summary内找到 其中我只稍微追查Bunch Headers, Handles, Export GUIDS这几项而已, 其他项目因为传输不多所以我没有深入追。 Bunch Headers Bunch Header到底传了那些,可以在 Engine/Source/Runtime/Engine/Private/NetConnection.cpp 的UNetConnection::SendRawBunch() 里面追查到 大致上就是这个Bunch 是open/close,是不是reliable, channel index是多少等等的资讯 Bunch headers的资料量从我们开发端是很难省掉的, 不过引擎端因为Fornite持续在开发的关系,应该会不断地改进。 例如以前有Bunch.bIsDormant现在直接被合并进 enum EChannelCloseReason Bunch.CloseReason。 Export GUIDS 这个项目主要发生在Server 要同步一个新的Actor给client的时候, 需要利用GUID跟client建立对应关系。 如果是动态生成的物件,会直接使用物件的路径+名称,以字串的方式作为GUID传送 举例来说server生成一个新的需要同步的Actor 路径在Content/Gameplay/Character/Skill/BP_bbb 那麽生成这个actor就会产生Export GUIDS的项目 在network profiller可以看到,大小至少是 Gameplay/Character/Skill/BP_bbb 31个Bytes。 会说至少是因为前後还会再加上Prefix以及Suffix,所以实际会更多。 除此之外,如果BP_bbb这个Actor的component也勾了component replicate的话 这个component也会产生Export GUIDS的项目。 也就是说如果你的游戏很频繁的动态生成物件,那麽Export GUIDS这个项目会很高。 但是Export GUIDS是可以透过物件池改善的。 同一个Actor可以重复使用的话就不用传GUID。 当然网路版本的物件池如何同步状态又是另一个难题了~ 有关Export GUIDS输出的程式码大约是在 Engine/Source/Runtime/Engine/Private/PackageMapClient.cpp UPackageMapClient::SerializeNewActor-> UPackageMapClient::SerializeObject-> UPackageMapClient::InternalWriteObject 有需要可以从这几个地方开始追。 Handles FNetworkProfiler::TrackWritePropertyHandle这个函式就是 用来处理Handles的项目,而呼叫的地方都是从 Engine/Source/Runtime/Engine/Private/RepLayout.cpp的 WritePropertyHandle触发的 如果搜寻程式码的话就可以知道Handle就是Server在Replicate Actor replicate变数的时候,用来告诉client後续的资料是哪个变数的 举例来说BP_bbb有三个可同步的integer变数var1, var2, var3 如果只有var2有改变,var2的值从0变成1 那server 就需要送类似 BP_bbb (var2, 1) 这样的资料给Client。 而var2要怎麽表示让client知道,就是由Handle负责。 基本上就是每个变数依照顺序给编号,所以var1=1, var2=2, var3=3 经由转换後就是 BP_bbb (2, 1) 不过因为server需要让client知道property资料传完了, 所以最後还要传编号0作为property的结束 也就是BP_bbb (2, 1, 0) Array property的情况就更复杂了 除了array property的index,最後也要加上编号0作Array结束的识别证明。 详细传Array的过程的额外细节我就没有特别追查, 总之记得成本比一般的property多就对了。 Handle的传输细节 Handle的变数宣告为uint16,所以如果我们传var2的资料(2, 1), 大小会是多少呢? 在实际输出Handle的时候,因为呼叫了 Writer.SerializeIntPacked(LocalHandle) 所以不会每次输出都是2+4 Bytes。但是还是有一定的大小 输出的实际程式码在 Engine/Source/Runtime/Core/Private/Serialization/BitWriter.cpp FBitWriter::SerializeIntPacked(uint32& InValue) 里面,有需要可以追一下。 Worst Case 上述的范例 假设handle是1 Byte 那麽传递一个integer实际上是 4/(4+1) = 80% 等於有20%是overhead 如果我们要同步的变数只有1bit的boolean呢? 最後可能要传9Bits 1/ (8+1) = 11% 等於接近90%的传输都是overhead... 贵爆! 改善Handle的Overhead 有一个作法可以避免replicate每个property前面都要带一个handle 那就是把多个property包成一个structure 并且实作这个structure的NetSerialize() 如此一来 这多个property的传输只会共用一个handle来处理 范例 http://www.aclockworkberry.com/custom-struct-serialization-for-networking-in-unreal-engine/ 可以参考这篇文章来实作。或是直接搜寻引擎程式码,有很多范例 缺点 整个structure实作NetSerialize後有一个重大的缺点 就是在计算变动的时候也是以整个structure作记忆体比较 所以整个structure如果只要有一个变数变动 也会呼叫NetSerialize并输出。 原来的版本因为各个property拆开,所以每个property会独自作记忆体比较再输出 所以如果整个structure常常只有少部分变动的话, 有可能实作NetSerialize反而传输会变大。 实际上还是要在没实作NetSerialize+Handles跟实作可能会浪费, 取得平衡点。 追踪SerializeNewActor传输开销 除了Bunch Overhead属於比较隐密容易被漏掉的项目 Server spawn一个新的actor所需要的传输量, 其实在Network Profiler没有页面显示出来 除了从程式码可以稍微知道基本要传哪些资讯 , 最後实际上同步新的actor的资料量其实是非常难知道的 这边列出几个我知道的项目 ★GUIDS ★Transform与速度 ★Replicate Properties GUIDS 前面有提过,这个是NetworkProfiler内就能看到的项目 Transform, Rotation, Scale, Velocity等项目是要传输, 但无法在Profiler内找到的。 最後是这个actor需要replicate的各个变数,如果与预设值不同就会传输。 这部份在NetworkProfiler可以看的到。 程式码可以看到在传各个Transform, Rotation, Scale. Velocity之前 会先给一个bit告知是不是预设值,如果是预设值的话就直接不传了。 这个传输技巧还蛮值得学习,可以应用在NetSerialize实作的时候, 搜寻引擎程式码也会看到这个技巧被大量应用在各个需要传输的地方。 然後因为Transform, Rotation等等都有自己的NetSerialize版本。 所以传输的资料量是变动的,造成SerializeNewActor的成本很难预估。 另一个值得注意的是Vector是使用FVector_NetQuantize10, Rotation是使用FRotator。 平常有需要同步座标或旋转的时候,记得使用这两种类型来降低传输。 以上就是有关网路传输开销的内容 Gameplay Network 传输相关的内容会暂时告一段落,目前没有新的项目要分享。 不过如果有想知道UE4的课题,也欢迎让我知道,谢谢~ --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 1.169.24.134 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/GameDesign/M.1561645395.A.11B.html
1F:推 coolrobin: 同样未看先推 06/28 21:00
2F:→ adm123: 你有FB吗?想订阅 06/29 10:53
3F:→ yekdniw: 抱歉 可能没时间经营FB~ 07/02 01:23
4F:→ yekdniw: 但是我文章会出没在discord跟PTT 07/02 01:23
※ 编辑: yekdniw (59.120.146.90 台湾), 07/15/2020 11:05:09







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:BuyTogether站内搜寻

TOP