40 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			40 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
|  | # Aliasing and the job system
 | ||
|  | 
 | ||
|  | Unity's job system infrastructure has some limitations on what can alias within a job struct: | ||
|  | 
 | ||
|  | * Structs attributed with [`[NativeContainer]`](https://docs.unity3d.com/ScriptReference/Unity.Collections.LowLevel.Unsafe.NativeContainerAttribute.html) (for example, [`NativeArray`](https://docs.unity3d.com/ScriptReference/Unity.Collections.NativeArray_1.html) and [`NativeSlice`](https://docs.unity3d.com/ScriptReference/Unity.Collections.NativeSlice_1.html)) that are members of a job struct don't alias. | ||
|  | * Job struct members with the [`[NativeDisableContainerSafetyRestriction]`](https://docs.unity3d.com/ScriptReference/Unity.Collections.LowLevel.Unsafe.NativeDisableContainerSafetyRestrictionAttribute.html) attribute can alias with other members. This is because this attribute explicitly opts in to this kind of aliasing. | ||
|  | * Pointers to structs attributed with `[NativeContainer]` can't appear in other structs attributed with `[NativeContainer]`. For example, you can't have a `NativeArray<NativeSlice<T>>`. | ||
|  | * Job structs are by default `[NoAlias]` structs, i.e. the address of the struct is not allowed to alias with its members. | ||
|  | 
 | ||
|  | It is possible to opt out of these aliasing guarantees for job structs and for their members by using the experimental attribute `[Alias]`, which is gated behind the `UNITY_BURST_EXPERIMENTAL_ALIAS_ATTRIBUTE` preprocessor define. | ||
|  | 
 | ||
|  | The following example job shows how these limitations work in practice: | ||
|  | 
 | ||
|  | ```c# | ||
|  | [BurstCompile] | ||
|  | private struct MyJob : IJob | ||
|  | { | ||
|  |     public NativeArray<float> a; | ||
|  |     public NativeArray<float> b; | ||
|  |     public NativeSlice<int> c; | ||
|  | 
 | ||
|  |     [NativeDisableContainerSafetyRestriction] | ||
|  |     public NativeArray<byte> d; | ||
|  | 
 | ||
|  |     public void Execute() { ... } | ||
|  | } | ||
|  | ``` | ||
|  | 
 | ||
|  | * `a`, `b`, and `c` don't alias with each other. | ||
|  | * `d` can alias with `a`, `b`, or `c`. | ||
|  | 
 | ||
|  | >[!TIP] | ||
|  | >If you're used to working with C/C++'s [Type Based Alias Analysis (TBAA)](https://en.wikipedia.org/wiki/Alias_analysis#Type-based_alias_analysis), then you might assume that because `d` has a different type from `a`, `b`, or `c`, it shouldn't alias. However, in C#, pointers don't have any assumptions that pointing to a different type results in no aliasing. This is why `d` is assumed to alias with `a`, `b`, or `c`. | ||
|  | 
 | ||
|  | ## Additional resources
 | ||
|  | 
 | ||
|  | * [Memory aliasing](aliasing.md) | ||
|  | * [NoAlias attribute](aliasing-noalias.md) | ||
|  | * [Job system](xref:um-job-system) |