五、C# Job System中NativeContainer

NativeContainer

 the safety system’s复制数据的过程的缺点是它还隔离了每个副本中作业的结果。 要克服此限制,您需要将结果存储在一种名为NativeContainer的共享内存中。

What is a NativeContainer?

NativeContainer是一种托管值类型,为本机内存提供相对安全的C#包装器。 它包含指向非托管分配的指针。 与Unity C#作业系统一起使用时,NativeContainer允许作业访问与主线程共享的数据,而不是使用副本。

有哪些类型的NativeContainer?

Unity附带一个名为NativeArray的NativeContainer。 您还可以使用NativeSlice操作NativeArray,以将NativeArray的子集从特定位置获取到特定长度。

注意:实体组件系统(ECS)包扩展Unity.Collections命名空间以包含其他类型的NativeContainer:

NativeList  - 可调整大小的NativeArray。
NativeHashMap  - 键和值对。
NativeMultiHashMap  - 每个键有多个值。
NativeQueue  - 先进先出(FIFO)队列。

NativeContainer and the safety system(安全系统)

the safety system内置于所有NativeContainer类型中。它跟踪正在读取和写入任何NativeContainer的内容。

注意:对NativeContainer类型的所有安全检查(例如越界检查,释放检查和竞争条件检查)仅在Unity编辑器和播放模式下可用。

该the safety system的一部分是DisposeSentinel和AtomicSafetyHandle。 DisposeSentinel检测到内存泄漏,如果您没有正确释放内存,则会出错。泄漏发生后很久就会发生内存泄漏错误。

使用AtomicSafetyHandle在代码中转移NativeContainer的所有权。例如,如果两个预定作业正在写入同一个NativeArray,则安全系统会抛出一个异常,并显示一条明确的错误消息,说明解决问题的原因和方法。安排违规工作时,安全系统会抛出此异常。

在这种情况下,您可以安排具有依赖关系的作业。第一个作业可以写入NativeContainer,一旦完成执行,下一个作业就可以安全地读取和写入同一个NativeContainer。从主线程访问数据时,读写限制也适用。安全系统允许多个作业并行读取相同的数据。

默认情况下,当作业可以访问NativeContainer时,它具有读写访问权限。此配置可能会降低性能。 C#作业系统不允许您安排具有对NativeContainer具有写访问权限的作业,而该作业与写入该作业的另一个作业同时进行。

如果job不需要写入NativeContainer,请使用[ReadOnly]属性标记NativeContainer,如下所示:

[ReadOnly]
public NativeArray<int> input;

 

在上面的示例中,您可以与其他具有对第一个NativeArray的只读访问权限的作业同时执行作业。

注意:无法防止从job中访问静态数据。 访问静态数据会绕过所有安全系统,并可能导致Unity崩溃。 有关更多信息,请参阅C# Job System提示和故障排除。

NativeContainer Allocator

创建NativeContainer时,必须指定所需的内存分配类型。分配类型取决于作业运行的时间长度。通过这种方式,您可以定制分配以在每种情况下获得最佳性能。

NativeContainer内存分配和释放有三种Allocator类型。在实例化NativeContainer时需要指定适当的一个。

Allocator.Temp分配最快。

它适用于寿命为一帧或更少的分配。您不应该使用Temp将NativeContainer分配传递给作业。您还需要在从方法调用返回之前调用Dispose方法(例如MonoBehaviour.Update,或从本机代码到托管代码的任何其他回调)。


Allocator.TempJob是比Temp更慢的分配,但比Persistent更快。

它适用于四帧生命周期内的分配,并且是线程安全的。如果不在四帧内处理它,控制台将打印一个从本机代码生成的警告。大多数小作业使用此NativeContainer分配类型。


Allocator.Persistent是最慢的分配,但只要你需要它,并且如果有必要,可以持续整个应用程序的生命周期。

它是直接调用malloc的包装器。较长的作业可以使用此NativeContainer分配类型。在性能至关重要的情况下,不应使用Persistent。

For example:

NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);

 注意:上例中的number 1表示NativeArray的大小。 在这种情况下,它只有一个数组元素(因为它只在结果中存储一个数据)。

来自:https://docs.unity3d.com/Manual/JobSystemNativeContainer.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值