Unity Burst详解

news2025/1/9 14:57:57

【简介】

Burst是Unity的编译优化技术,优化了从C#代码编译成Native代码的过程,经过编译优化后代码有更高的运行效率。

在Unity中使用Burst很简单,在方法或类前加上[BurstCompile]特性即可。在构建时编译代码的步骤,Burst编译器会识别该特性对方法或类做编译优化。其适用于高性能计算的场景,逻辑复杂的场景不适用。

Burst编译的实现得益于已有的SIMD和LLVM技术。

【SIMD】

在现代 CPU 中,并行性操作大致分为三种类型:

  • 指令级并行,主要由 cpu 流水线技术,乱序执行技术等技术完成
  • 线程级并行,主要依靠多核多线程技术实现
  • 数据级并行,主要依靠 SIMD (单指令多数据) 来实现

SIMD是CPU硬件设计的一部分,是的CPU可以同时对多个数据执行相同的操作。

指令执行时(指令由操作码和操作数构成)CPU先访问缓存,缓存分为指令缓存和数据缓存,如果缓存中有指令就读取,没有指令从内存中读取;读取数据的过程也类似。

以加法为例,对于5+2这个加法计算,最少需要四条指令:

  1. 将数值 5 加载到寄存器中(LOAD操作码)
  2. 将数值 2 加载到寄存器中(LOAD操作码)
  3. 将两个寄存器中的数值相加(ADD操作码)
  4. 将相加后的结果存储到指定的寄存器或内存中(STORE操作码)

在SISD(单指令单数据)中,每个指令只会取一次数据,而在SIMD(单指令多数据)中,一次指令会取多个数据,节省了CPU获取数据的时间。

一次性取出来的数放在向量寄存器中,但向量寄存器大小有限,在AVX指令集中有256位。

在C#中,float类型占64位,一般要4个float类型一组。

现代编译器有三种方式来支持 SIMD:

  • 编译器能够在没有用户干预的情况下生成支持使用硬件SIMD的代码,称之为自动矢量化
  • 通过使用的Intrinsics 函数实现 SIMD
  • 使用矢量 C++ 类 (仅限ICC编译器) 来实现 SIMD

(Intrinsics函数是一种内建函数,它们用于实现高级别的底层操作。这些函数通常由编译器提供,并且可以直接映射到特定的硬件指令。使用Intrinsics函数可以实现对特定硬件功能的直接访问,从而提高代码的性能和效率。

内联函数通常用关键字inline声明,是由编译器处理的普通函数,编译器会根据需要将函数内容直接插入到调用处,减少了函数调用的开销。而Intrinsics函数一般不需要显式声明,编译器会自动识别并将其优化为特定的硬件指令 )

Unity.Mathematics提供了支持SIMD的数据类型,例如float4/int4等类型,在Job中需要使用这些数据类型。

在Job中要多用float4类型才有效,例如有一个float类型的数组,可以转为float4类型的数组,有利于在循环计算时自动矢量化。

【LLVM】

传统编译器架构为:

frontEnd(前端)检查源代码是否存在错误,将源代码分析成词法单元,然后进行语法分析生成抽象语法树,生成中间IR语言

Optimizer(优化) 对中间IR语言进行优化,消除冗余计算,内联、变量折叠等

BackEnd(后端) 最终将IR中间语言生成目标机器所能执行的代码

这种问题在于不同语言都要有各自的编译器和优化手段,LLVM期望提供一种IR标准,不同语言经过编译后先生成LLVM IR语言,只需要针对其做优化即可。

新增一个语言时,只需新实现一个前端,新增一种设备后,只需新实现一个后端

BurstCompiler会根据特性找到需要编译的方法,将方法对应的C# IR转为LVVM IR,随后针对LVVM IR做优化,编译。

【Burst使用】

支持的类型和语法

可以简单的将BurstCompile特性至于方法或类上,但不是所有的方法和类都支持。情况如下:

  • 支持基元类型:bool/byte/int/long/float/double,不支持char、string、decimal
  • 支持Unity.Mathematics中的向量类型,例如bool3\bool4\int3\int4\float3\float4等
  • 支持枚举类型、结构体、元组、System.IntPtr、Span<T>
  • 支持DllImport and internal calls 
  • 不支持Managed Array,例如int[] a;支持NativeArray
  • 方法中不能引用managed object
  • 不支持Try Catch语法

打Log

代码中Log是少不了的,Burst对Debug.Log有额外支持,例如:

Debug.Log("This a string literal");


int value = 256;
Debug.Log($"This is an integer value {value}"); 

//string需要使用FixedString,例如:
FixedString128Bytes str = "fixedstring128";
Debug.Log(str);

 编译检查

为避免在构建时才发现Burst编译不过,提供了Burst Inspector可以在Editor下预编译,以便查看编译结果

通过Jobs > Burst > Open Inspector 打开可视化面板,面板会显示编译结果

面板左边显示了可以正常编译得Job,右边显示当前选中的Job的编译结果,依次是:

  • Assembly:最终优化生成的NativeCode
  • .NET IL:原始的C# Job代码生成的IL
  • LLVM IR (Unoptimized) :未优化的LLVM IR
  • LLVM IR (Optimized):优化后的LLVM IR
  • LLVM IR Optimization Diagnostics:提供优化诊断细节

舍弃编译

当在类或结构体添加BurstCompile特性后,默认对其内所有方法做编译,如果某个方法我们使用了Managed Object而不想编译,可以使用[BurstDiscard]特性。

注意,使用该特性时,方法不能有返回值,可以通过ref或者out传递返回值

同步编译

Editor上Job是默认异步编译的,首次执行到Job时才会异步编译。通过[BurstCompile(CompileSynchronously = true)]开启同步编译

精度设定

浮点数精度会影响计算性能,默认采用中等精度,可以通过[BurstCompile(FloatPrecision.Med, FloatMode.Fast)]指定精度

指定取值范围

对参数和返回值指定取值范围有利于编译器做特定的代码优化,例如

[return:AssumeRange(0u, 13u)]
static uint WithConstrainedRange([AssumeRange(0, 26)] int x)
{
    return (uint)x / 2u;
}

分支指定

 可以通过Unity.Burst.CompilerServices.Hint.Likely告诉编译器该分支大概率为true,需要重点优化,例如

if (Unity.Burst.CompilerServices.Hint.Likely(b))
{
    // Any code in here will be optimized by Burst with the assumption that we'll probably get here!
}
else
{
    // Whereas the code in here will be kept out of the way of the optimizer.
}

【参考】

深入浅出让你理解什么是LLVM - 简书

https://zhuanlan.zhihu.com/p/472813616

Quick Start | Burst | 1.7.4

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2273851.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

el-table 合并单元格

参考文章&#xff1a;vue3.0 el-table 动态合并单元格 - flyComeOn - 博客园 <el-table :data"tableData" border empty-text"暂无数据" :header-cell-style"{ background: #f5f7fa }" class"parent-table" :span-method"obj…

WebRTC 在视频联网平台中的应用:开启实时通信新篇章

在当今这个以数字化为显著特征的时代浪潮之下&#xff0c;实时通信已然稳稳扎根于人们生活与工作的方方面面&#xff0c;成为了其中不可或缺的关键一环。回首日常生活&#xff0c;远程办公场景中的视频会议让分散各地的团队成员能够跨越地理距离的鸿沟&#xff0c;齐聚一堂共商…

OpenAI CEO 奥特曼发长文《反思》

OpenAI CEO 奥特曼发长文《反思》 --- 引言&#xff1a;从 ChatGPT 到 AGI 的探索 ChatGPT 诞生仅一个多月&#xff0c;如今我们已经过渡到可以进行复杂推理的下一代模型。新年让人们陷入反思&#xff0c;我想分享一些个人想法&#xff0c;谈谈它迄今为止的发展&#xff0c;…

网络空间安全导论期末考试复习题

题型&#xff1a;10个选择题10个大题 1、选择题 简单&#xff0c;记忆书本里的小标题 2、大题&#xff08;较难&#xff09; 网络安全体系的五个层次的内容画公钥密码结合报文鉴别的示意图解释误用入侵检测并画示意图解释隧道技术并画示意图防火墙的作用&#xff0c;防火墙和…

接口测试-postman(使用postman测试接口笔记)

一、设置全局变量 1. 点击右上角设置按钮-》打开管理环境窗口-》选择”全局“-》设置变量名称&#xff0c;初始值和当前值设置一样的&#xff0c;放host放拼接的url&#xff0c;key放鉴权那一串字符&#xff0c;然后保存-》去使用全局变量&#xff0c;用{{变量名称}}形式 二、…

每日一题-两个链表的第一个公共结点

文章目录 两个链表的第一个公共结点问题描述示例说明示例 1示例 2 方法及实现方法描述代码实现 复杂度分析示例运行过程示例 1示例 2 总结备注 两个链表的第一个公共结点 问题描述 给定两个无环的单向链表&#xff0c;找到它们的第一个公共节点。如果没有公共节点&#xff0c…

API架构风格的深度解析与选择策略:SOAP、REST、GraphQL与RPC

❃博主首页 &#xff1a; 「码到三十五」 &#xff0c;同名公众号 :「码到三十五」&#xff0c;wx号 : 「liwu0213」 ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a…

【搜索】【推荐】大 PK

引言 在当今信息爆炸的时代&#xff0c;如何从海量数据中精准地为用户推荐最相关的内容成为了科技领域的关键挑战。搜推技术作为推荐系统的核心组件&#xff0c;扮演着至关重要的角色。本文将深入探讨这两种技术背后的方法论&#xff0c;剖析它们各自面临的难点&#xff0c;并…

[uniapp] 实现扫码功能,含APP、h5、小程序

&#x1f680; 个人简介&#xff1a;某大型国企资深软件开发工程师&#xff0c;信息系统项目管理师、CSDN优质创作者、阿里云专家博主&#xff0c;华为云云享专家&#xff0c;分享前端后端相关技术与工作常见问题~ &#x1f49f; 作 者&#xff1a;码喽的自我修养&#x1f9…

mysql、postgresql、druid链接池踩坑记录

The last packet successfully received from the server wIs 10,010 milliseconds ago. The last packet sent successfully to the server was 10,010 milliseconds ago.### The error may exist in URL mysql 链接字符串没有 &connectTimeout600000&socketTimeout6…

STM32+WIFI获取网络时间+8位数码管显示+0.96OLED显

资料下载地址&#xff1a;STM32WIFI获取网络时间8位数码管显示0.96OLED 1、项目介绍 主控芯片STM32C8T6 接线&#xff1a;串口1&#xff1a;PA9 PA10 OELD &#xff1a;PB6 PB7 数码管使用&#xff1a;MAX7219 8位数码管 Max7219_pinCLK PAout(5) Max7219_pinC…

FPGA车牌识别

基于FPGA的车牌识别主要包含以下几个步骤&#xff1a;图像采集、颜色空间转换、边缘检测、形态学处理&#xff08;腐蚀和膨胀&#xff09;、特征值提取、模板匹配、结果显示。先用matlab对原理进行仿真&#xff0c;后用vivado和modelsim进行设计和仿真。 一、1.图像采集采用ov…

一文流:Mysql进阶(多图提醒⚠️)

一文流系列是作者苦于技术知识学了-忘了&#xff0c;背了-忘了的苦恼&#xff0c;决心把技术知识的要点一笔笔✍️出来&#xff0c;一图图画出来&#xff0c;一句句讲出来&#xff0c;以求刻在&#x1f9e0;里。 该系列文章会把核心要点提炼出来&#xff0c;以求掌握精髓&#…

深度学习从入门到实战——卷积神经网络原理解析及其应用

卷积神经网络CNN 卷积神经网络前言卷积神经网络卷积的填充方式卷积原理展示卷积计算量公式卷积核输出的大小计算感受野池化自适应均值化空洞卷积经典卷积神经网络参考 卷积神经网络 前言 为什么要使用卷积神经网络呢&#xff1f; 首先传统的MLP的有什么问题呢&#xff1f; - …

自动化脚本本地可执行但是Jenkins上各种报错怎么解决

作者碎碎念&#xff1a; 测试环境 Jenkinsdockerpythonunittest&#xff0c; 测试问题&#xff1a;本人在写关于SAP4Me网站的自动化脚本时遇到一个问题 本地怎么都跑的通 但是一上Jenkins会出现各种各样的问题 因为在Jenkins里面脚本是放在docker环境里面跑的 所以环境的差异…

【xLua】xLua-master签名、加密Lua文件

GitHub - Tencent/xLua: xLua is a lua programming solution for C# ( Unity, .Net, Mono) , it supports android, ios, windows, linux, osx, etc. 如果你想在项目工程上操作&#xff0c;又发现项目工程并没导入Tools&#xff0c;可以从xLua-master工程拷贝到项目工程Assets…

Linux(上):基本知识篇

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、Linux初识1 Linux简介2 Linux学习环境配置(1)安装Linux(2)FinalShell远程连接Linux服务器二、Linux基础命令1 Linux目录结构,根目录 /2 Linux命令基础(1)什么是命令、命令行?(2)…

【安卓开发】【Android Studio】项目构建失败提示【Could not read metadata.bin】解决方法

一、问题说明 在Android Studio中开发安卓项目时&#xff0c;项目构建失败&#xff0c;提示如下&#xff1a; Could not read workspace data from xxx/xxx/&#xff08;某个目录&#xff0c;和gradle有关&#xff09;&#xff1a;could not read ...metadata.bin&#xff08…

细说STM32F407单片机以轮询方式读写外部SRAM的方法

目录 一、实例的功能 二、工程配置 1、KEYLED 2、时钟、DEBUG、USART6、NVIC、GPIO、CodeGenerator 3、FSMC &#xff08;1&#xff09; 模式设置 &#xff08;2&#xff09; Bank 1子区3参数设置 1) NOR/PSRAM control组&#xff0c;子区控制参数 2) NOR/PSRAM timi…

下载ffmpeg执行文件

打开网址&#xff1a;Download FFmpeg 按下面步骤操作 解压文件就可以看到ffmpeg的执行文件了&#xff0c;需要通过命令行进行使用&#xff1a; ffmpeg命令行使用参考&#xff1a; ffmpeg 常用命令-CSDN博客