为什么 NativeArray 需要从 Unity 的 Job System 获取 return 值?
Why is NativeArray needed to obtain return values from Unity's Job System?
使用下面的代码块作为参考,单个更新提供以下结果:
intReturn = 0
inputArrayReturn = 1
internalArrayReturn = 1
这里唯一对我有意义的值是 internalArrayReturn
。
为什么 intReturn
不等于 1? 是什么导致了 stuct 的值没有改变,即使在执行期间它应该添加 1它?如果这只是 NativeArray 和 int 之间的根本区别,有人可以解释一下或给我指出一个可以帮助我更好地理解这一点的参考吗?
另外,为什么inputArrayReturn
不等于0? NativeArray
是一个结构,所以它不应该被视为值的副本而不是在 testArray = testArrayResults
行执行时引用?如果是这种情况,那么 inputArrayReturn
将保持等于 0 而不是更新为包含在 testJob.testArray
.
中的相同值
using UnityEngine;
using Unity.Jobs;
using Unity.Collections;
public class ParallelTesting : MonoBehaviour
{
void Update()
{
NativeArray<int> testArrayResults = new NativeArray<int>(1, Allocator.TempJob);
TestJob testJob = new TestJob
{
testInt = 0,
testArray = testArrayResults
};
JobHandle testJobHandle = testJob.Schedule();
testJobHandle.Complete();
int intReturn = testJob.testInt;
int inputArrayReturn = testArrayResults[0];
int internalArrayReturn = testJob.testArray[0];
testArrayResults.Dispose();
}
public struct TestJob : IJob
{
public int testInt;
public NativeArray<int> testArray;
public void Execute()
{
testInt += 1;
testArray[0] = testInt;
}
}
}
没有专家,但我会说 NativeArray
是专门为线程保存而设计的,基本上是 Unity 主线程和作业之间的共享内存 system/runner。
是的,NativeArray
是一个结构 ,但 事实上,如果你看一下 source code,它基本上只是一个包含指向实际结构的指针的包装器内存中的本机缓冲区。
public unsafe struct NativeArray<T> : IDisposable, IEnumerable<T>, IEquatable<NativeArray<T>> where T : struct
{
[NativeDisableUnsafePtrRestriction]
internal void* m_Buffer;
internal int m_Length;
internal int m_MinIndex;
internal int m_MaxIndex;
...
这就是为什么两者
int inputArrayReturn = testArrayResults[0];
int internalArrayReturn = testJob.testArray[0];
通过相同的指针访问相同的外部存储器,因此 return 相同且正确的值。
然而,“正常”int
不一定是线程安全的,因为它没有分配外部内存(请参阅 Heap and Stack)并且您的 Unity 主线程不知道作业在内部发生了变化它在不同 thread/core.
上时的价值
Why doesn't intReturn equal 1?
因为 Unity.Jobs
使用在托管内存外部分配的专用内存块(本机容器、Unity.Collections
、指针)和 testInt
,虽然为工作线程编组,但未分配到外部任何地方堆叠.
Also, why doesn't inputArrayReturn equal 0?
因为 testArrayResults
和 testJob.testArray
都是同一个指针的副本,所以它们都引用发生在 new NativeArray<int>(1, Allocator.TempJob)
的相同分配。
Why is NativeArray needed to obtain return values from Unity's Job System?
这只是线程安全问题的一个很好的标准化解决方案,因为围绕这些容器的工具会警告您所有依赖关系、竞争条件等方式。
注意:您可以使用具有 [NativeDisableUnsafePtrRestriction]
属性的指针。但坚持使用本机容器更安全。
使用下面的代码块作为参考,单个更新提供以下结果:
intReturn = 0
inputArrayReturn = 1
internalArrayReturn = 1
这里唯一对我有意义的值是 internalArrayReturn
。
为什么 intReturn
不等于 1? 是什么导致了 stuct 的值没有改变,即使在执行期间它应该添加 1它?如果这只是 NativeArray 和 int 之间的根本区别,有人可以解释一下或给我指出一个可以帮助我更好地理解这一点的参考吗?
另外,为什么inputArrayReturn
不等于0? NativeArray
是一个结构,所以它不应该被视为值的副本而不是在 testArray = testArrayResults
行执行时引用?如果是这种情况,那么 inputArrayReturn
将保持等于 0 而不是更新为包含在 testJob.testArray
.
using UnityEngine;
using Unity.Jobs;
using Unity.Collections;
public class ParallelTesting : MonoBehaviour
{
void Update()
{
NativeArray<int> testArrayResults = new NativeArray<int>(1, Allocator.TempJob);
TestJob testJob = new TestJob
{
testInt = 0,
testArray = testArrayResults
};
JobHandle testJobHandle = testJob.Schedule();
testJobHandle.Complete();
int intReturn = testJob.testInt;
int inputArrayReturn = testArrayResults[0];
int internalArrayReturn = testJob.testArray[0];
testArrayResults.Dispose();
}
public struct TestJob : IJob
{
public int testInt;
public NativeArray<int> testArray;
public void Execute()
{
testInt += 1;
testArray[0] = testInt;
}
}
}
没有专家,但我会说 NativeArray
是专门为线程保存而设计的,基本上是 Unity 主线程和作业之间的共享内存 system/runner。
是的,NativeArray
是一个结构 ,但 事实上,如果你看一下 source code,它基本上只是一个包含指向实际结构的指针的包装器内存中的本机缓冲区。
public unsafe struct NativeArray<T> : IDisposable, IEnumerable<T>, IEquatable<NativeArray<T>> where T : struct { [NativeDisableUnsafePtrRestriction] internal void* m_Buffer; internal int m_Length; internal int m_MinIndex; internal int m_MaxIndex; ...
这就是为什么两者
int inputArrayReturn = testArrayResults[0];
int internalArrayReturn = testJob.testArray[0];
通过相同的指针访问相同的外部存储器,因此 return 相同且正确的值。
然而,“正常”int
不一定是线程安全的,因为它没有分配外部内存(请参阅 Heap and Stack)并且您的 Unity 主线程不知道作业在内部发生了变化它在不同 thread/core.
Why doesn't intReturn equal 1?
因为 Unity.Jobs
使用在托管内存外部分配的专用内存块(本机容器、Unity.Collections
、指针)和 testInt
,虽然为工作线程编组,但未分配到外部任何地方堆叠.
Also, why doesn't inputArrayReturn equal 0?
因为 testArrayResults
和 testJob.testArray
都是同一个指针的副本,所以它们都引用发生在 new NativeArray<int>(1, Allocator.TempJob)
的相同分配。
Why is NativeArray needed to obtain return values from Unity's Job System?
这只是线程安全问题的一个很好的标准化解决方案,因为围绕这些容器的工具会警告您所有依赖关系、竞争条件等方式。
注意:您可以使用具有 [NativeDisableUnsafePtrRestriction]
属性的指针。但坚持使用本机容器更安全。