Unity 可从磁盘加载纹理和网格数据,并以两种不同方式将数据上传到 GPU:同步或异步。这两个过程称为同步上传管线和异步上传管线。
当 Unity 使用同步上传管线时,在加载和上传数据时无法执行其他任务。这种情况下可能会导致应用程序出现明显的暂停。当 Unity 使用异步上传管线时,数据在后台加载和上传,同时可以执行其他任务。
如果某个纹理或网格适合异步上传管线,则 Unity 会自动使用异步上传管线。如果某个纹理或网格不适合异步上传管线,则 Unity 会自动使用同步上传管线。
同步和异步上传管线之间的主要区别是 Unity 在构建时保存数据的位置,这会影响 Unity 在运行时加载数据的方式。
在同步上传管线中,Unity 必须在单个帧中同时加载纹理或网格的元数据(标头数据)和纹素或顶点数据(二进制数据)。在异步上传管线中,Unity 必须在单个帧中仅加载标头数据,并可以在后续帧中将二进制数据流式传输到 GPU。
在同步上传管线中:
在异步上传管线中:
如果满足以下条件,纹理适合异步上传管线:
请注意,如果使用 LoadImage(byte[] data)
来加载纹理,即使满足上述条件,仍会强制 Unity 使用同步上传管线。
如果满足以下条件,网格适合异步上传管线:
在所有其他情况下,Unity 会同步加载纹理和网格。
可使用性能分析器或其他性能分析工具通过观察线程活动和性能分析器标记来确定 Unity 在何时使用了异步上传管线。
以下内容表明 Unity 正在使用异步上传管线来上传纹理或网格:
AsyncUploadManager.ScheduleAsyncRead
、AsyncReadManager.ReadFile
和 Async.DirectTextureLoadBegin
性能分析器标记。AsyncRead
线程上的活动。如果没有看到此活动,则表明 Unity 没有使用异步上传管线。
请注意,以下性能分析器标记并不表示 Unity 正在使用异步上传管线;Unity 调用它们来检查是否需要进行任何异步上传工作:
Initialization.AsyncUploadTimeSlicedUpdate
AsyncUploadManager.AsyncResourceUpload
AsyncUploadManager.ScheduleAsyncCommands
可配置异步上传管线的以下设置。请注意,无法配置同步上传管线的设置。
Unity 重复使用单个环形缓冲区将纹理和网格数据流式传输到 GPU。如此将减少所需的内存分配次数。
The Async Upload Buffer determines the size of this ring buffer. It has a minimum size of 2 megabytes, and a maximum size of 2047 megabytes.
Unity 会自动调整缓冲区的大小以适应当前加载的最大纹理或网格。这可能是一个缓慢的操作,尤其是在 Unity 必须多次执行该操作的情况下;例如,如果要加载许多大于默认缓冲区大小的纹理,则属于这种情况。为了减少 Unity 必须调整缓冲区大小的次数,请设置该值以适合您期望加载的最大值。通常这是场景中最大的纹理。
可在 Quality settings 窗口中或使用 QualitySettings.asyncUploadBufferSize API 来配置该值。
Async Upload Time Slice 是 CPU 将纹理或网格数据上传到 GPU 时花费的时间量(以毫秒/帧为单位)。
较大的值表示数据将更快地在 GPU 上准备就绪,但是 CPU 将在这些帧期间花费更多时间进行上传操作。请注意,只有在缓冲区中有数据等待上传到 GPU 时,Unity 才使用此时间进行上传;如果没有等待的数据,Unity 可以将此时间用于其他操作。
可在 Quality settings 窗口中或使用 QualitySettings.asyncUploadTimeSlice API 来配置该值。
有关异步上传纹理和网格数据的更多信息,请参阅 Unity 博客文章:优化加载性能:了解异步上传管线 (Optimizing loading performance: Understanding the Async Upload Pipeline)。