Skip to content

Commit

Permalink
更新DOTS文档
Browse files Browse the repository at this point in the history
  • Loading branch information
pirunxi committed May 11, 2024
1 parent 3e8b705 commit 3d23e46
Show file tree
Hide file tree
Showing 6 changed files with 274 additions and 57 deletions.
142 changes: 138 additions & 4 deletions docs/basic/dots.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,142 @@
# DOTS支持

DOTS的并不支持动态注册Component、System、Aspect等核心类型,导致热更新中的DOTS相关类型无法被DOTS运行时识别,无法正常运行。
DOTS的TypeManager初始化时机过早,而且不支持动态注册Component和System等类型。为了让热更新模块能在DOTS系统中正常
运行,需要对DOTS源码进行修改,调整World的的初始化时机。

商业化版本对DOTS做了部分修改,并且相应调整了运行时代码,最终实现了支持DOTS绝大多数特性。尤其是旗舰版本,标记`[BurstCompile]`的函数如果未修改,
可以直接调用burst函数实现,可以极大提升性能。
## 支持的版本

具体请参见[商业化版本的DOTS 支持](../business/dots)文档。
由于DOTS仍然在快速迭代和修改,为了减少维护成本,只维护以下几个版本的com.unity.entities:

- 0.51.1-preview.21
- 1.0.16

目前仅在Unity 2021+版本上完成测试,Unity 2020及更低版本未测试兼容性。一般来说,只要对应版本的com.unity.entities能
在该Unity版本上正常运行,也能支持hybridclr。

有特殊DOTS版本需求的开发者,由于维护单独的DOTS版本成本较高,需要联系我们单独付费定制。


## 支持的特性

目前绝大多数DOTS特性都可以在hybridclr下正常运行,只有跟BurstCompile及资源序列化相关的特性支持较差。

### 1.0.16版本

|特性|社区版本|专业版|旗舰版|热重载版|
|-|-|-|-|-|
|Jobs|||||
|Managed Component|||||
|Unmanaged Component|||||
|Managed System|||||
|Unmanaged System|||||
|Aspect|||||
|IJobEntity|||||
|BurstCompile|||||
|SubScene|||||

### 0.51.1-preview.21版本

|特性|社区版本|专业版|旗舰版|热重载版|
|-|-|-|-|-|
|Jobs|||||
|Managed Component|||||
|Unmanaged Component|||||
|Managed System|||||
|Unmanaged System|||||
|IJobEntity|||||
|BurstCompile|||||
|SubScene|||||

## 安装

### 安装com.unity.entities

- 在项目中移除 com.unity.entities包,退出Unity Editor,清空 `Library\PackageCache` 目录下该包对应的目录
- 根据项目使用的版本,下载[修改后的com.unity.entities](https://code-philosophy.feishu.cn/file/NH0cbaeneozfd8xdbvmcLNvfn2d),将对应目录下的`com.unity.entities.7z` 解压到 Packages目录。请确保解压后的目录名为com.unity.entities。

重新打开Unity Editor时可能会提示是否要进行Api升级,根据项目情况自行决定是否升级。

### 修改项目设置

为了避免DOTS运行过程中带动态注册Component或System可能引发的问题,需要调整World的初始化时机以确保运行所有World之前已经注册了所有热更新类型。

`Player Settings``Scripting Define Symbols`中,添加编译宏 `UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP_RUNTIME_WORLD`。详细介绍可以参见World的
[自定义初始化文档](https://docs.unity3d.com/Packages/[email protected]/manual/world.html)

### 初始化

为了避免遇到问题,请在**加载完热更新代码后,运行任何dots代码之前**进行初始化。

初始化中主要包含两部分:

- 注册热更新的dots类型
- 初始化World

不同的com.unity.entities版本的初始化实现略有差别。

0.51.1版本初始化代码如下:

```csharp
private static void InitializeWorld()
{
#if !UNITY_EDITOR
var dotsAssemblies = new Assembly[] { ... };
var componentTypes = new HashSet<System.Type>();
TypeManager.CollectComponentTypes(dotsAssemblies, componentTypes);
TypeManager.AddNewComponentTypes(componentTypes.ToArray());
TypeManager.EarlyInitAssemblies(dotsAssemblies);
#endif


DefaultWorldInitialization.Initialize("Default World", false);

}
```

1.0.16版本的初始化代码如下:

```csharp
private static void InitializeWorld()
{
#if !UNITY_EDITOR
var dotsAssemblies = new Assembly[] { ... };
var componentTypes = new HashSet<Type>();
TypeManager.CollectComponentTypes(dotsAssemblies, componentTypes);
TypeManager.AddComponentTypes(dotsAssemblies, componentTypes);
TypeManager.RegisterSystemTypes(dotsAssemblies);
TypeManager.InitializeSharedStatics();
TypeManager.EarlyInitAssemblies(dotsAssemblies);
#endif


DefaultWorldInitialization.Initialize("Default World", false);
}
```

### 解决ReversePInvokeCallback的问题

DOTS系统初始化Unmanaged System时会尝试获得它的OnStart之类函数的Marshal指针。hybridclr需要为每个这种函数绑定一个运行时唯一的cpp函数指针,
否则运行过程中会出现`GetReversePInvokeWrapper fail. exceed max wrapper num of method`错误。详细介绍可见[HybridCLR+lua/js/python](https://hybridclr.doc.code-philosophy.com/docs/basic/workwithscriptlanguage)文档。

简单来说,需要预留足够多的 SystemBaseRegistry.ForwardingFunc对应的 wrapper函数。在热更新模块(也可以在DHE程序集,但不能在AOT程序集)中添加如下代码:

```csharp
public static class PreserveDOTSReversePInvokeWrapper
{
[ReversePInvokeWrapperGeneration(100)]
[MonoPInvokeCallback(typeof(SystemBaseRegistry.ForwardingFunc))]
public static void ForwordMethod(IntPtr system, IntPtr state)
{

}
}


```

将代码中的100改为一个适当的数字即可,推荐为Unmanaged System类型个数的5-10倍。


### Burst相关

- 包含`[BurstCompile]`的热更新函数发生变化,需要去掉`[BurstCompile]`特性,否则运行会报错。这个问题后面可能会优化
46 changes: 0 additions & 46 deletions docs/business/dots.md

This file was deleted.

2 changes: 1 addition & 1 deletion docs/business/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
|补充元数据|||||
|增量式GC|||||
|Unity 2019-2022 LTS|||||
|[DOTS](./dots)|||||
|[完全泛型共享](./fullgenericsharing)|||||
|[DOTS](./dots)|||||
|[元数据优化](./metadataoptimization.md)|||||
|[标准解释性能优化](./basicoptimization)|||||
|[离线指令优化](./advancedoptimization)|||||
Expand Down
138 changes: 134 additions & 4 deletions i18n/en/docusaurus-plugin-content-docs/current/basic/dots.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,138 @@
# DOTS Support

DOTS does not support dynamic registration of core types such as Component, System, and Aspect. As a result, DOTS-related types in hot updates cannot be recognized by the DOTS runtime and cannot operate normally.
The initialization timing of TypeManager in DOTS is too early, and it does not support dynamically registering Component and System types. To ensure the normal operation of the hot update module in the DOTS system, modifications need to be made to the DOTS source code to adjust the initialization timing of the World.

The commercial version made some modifications to DOTS and adjusted the runtime code accordingly, ultimately supporting most of the features of DOTS. Especially for the flagship version, if the function marked `[BurstCompile]` is not modified,
It can be implemented by directly calling the burst function, which can greatly improve performance.
## Supported Versions

For details, please refer to the [Commercial version of DOTS support] (../business/dots) document.
Due to the rapid iteration and modification of DOTS, in order to reduce maintenance costs, only the following versions of com.unity.entities are maintained:

- 0.51.1-preview.21
- 1.0.16

Currently, compatibility testing has only been completed on Unity 2021+ versions, and compatibility with Unity 2020 and lower versions has not been tested. Generally, as long as the corresponding version of com.unity.entities can run normally on that Unity version, hybridclr support should also be available.

Developers with special requirements for DOTS versions need to contact us for separate customized payment due to the higher maintenance cost of maintaining separate DOTS versions.


## Supported Features

Currently, most DOTS features can run normally under hybridclr, except for features related to BurstCompile and resource serialization.

### Version 1.0.16

| Feature | Community Version | Professional Version | Enterprise Version | Hot Reload Version |
|------------------|-------------------|----------------------|--------------------|--------------------|
| Jobs |||||
| Managed Component |||||
| Unmanaged Component |||||
| Managed System |||||
| Unmanaged System |||||
| Aspect |||||
| IJobEntity |||||
| BurstCompile | | || |
| SubScene | | | | |

### Version 0.51.1-preview.21

| Feature | Community Version | Professional Version | Enterprise Version | Hot Reload Version |
|------------------|-------------------|----------------------|--------------------|--------------------|
| Jobs |||||
| Managed Component |||||
| Unmanaged Component |||||
| Managed System |||||
| Unmanaged System |||||
| IJobEntity |||||
| BurstCompile | | || |
| SubScene | | | | |

## Installation

### Installing com.unity.entities

- Remove the com.unity.entities package from the project, exit the Unity Editor, and clear the directory corresponding to the package under `Library\PackageCache`.
- Download the [modified com.unity.entities](https://code-philosophy.feishu.cn/file/NH0cbaeneozfd8xdbvmcLNvfn2d) according to the version used by the project, and unzip the `com.unity.entities.7z` in the corresponding directory to the Packages directory. Make sure that the directory name after decompression is com.unity.entities.

When reopening the Unity Editor, you may be prompted to perform API upgrades. Decide whether to upgrade according to the project situation.

### Modify Project Settings

To avoid potential issues caused by dynamically registering Component or System during DOTS runtime, adjust the initialization timing of World to ensure that all hot update types are registered before running all Worlds.

Add the compilation macro `UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP_RUNTIME_WORLD` in `Player Settings` under `Scripting Define Symbols`. For detailed instructions, refer to the World's [custom initialization documentation](https://docs.unity3d.com/Packages/[email protected]/manual/world.html).

### Initialization

To avoid encountering issues, perform initialization **after loading the hot update code and before running any dots code**.

Initialization mainly consists of two parts:

- Register hot update dots types.
- Initialize World.

There are slight differences in the initialization implementations of different versions of com.unity.entities.

For version 0.51.1, the initialization code is as follows:

```csharp
private static void InitializeWorld()
{
#if !UNITY_EDITOR
var dotsAssemblies = new Assembly[] { ... };
var componentTypes = new HashSet<System.Type>();
TypeManager.CollectComponentTypes(dotsAssemblies, componentTypes);
TypeManager.AddNewComponentTypes(componentTypes.ToArray());
TypeManager.EarlyInitAssemblies(dotsAssemblies);
#endif


DefaultWorldInitialization.Initialize("Default World", false);

}
```

For version 1.0.16, the initialization code is as follows:

```csharp
private static void InitializeWorld()
{
#if !UNITY_EDITOR
var dotsAssemblies = new Assembly[] { ... };
var componentTypes = new HashSet<Type>();
TypeManager.CollectComponentTypes(dotsAssemblies, componentTypes);
TypeManager.AddComponentTypes(dotsAssemblies, componentTypes);
TypeManager.RegisterSystemTypes(dotsAssemblies);
TypeManager.InitializeSharedStatics();
TypeManager.EarlyInitAssemblies(dotsAssemblies);
#endif


DefaultWorldInitialization.Initialize("Default World", false);
}
```

## Resolve ReversePInvokeCallback Issues

When initializing Unmanaged Systems, the DOTS system will attempt to obtain the Marshal pointer of its OnStart-like functions. hybridclr needs to bind a runtime-unique cpp function pointer for each of these functions, otherwise the error GetReversePInvokeWrapper fail. exceed max wrapper num of method will occur during runtime. For detailed instructions, refer to the HybridCLR+lua/js/python documentation.

In simple terms, a sufficient number of SystemBaseRegistry.ForwardingFunc corresponding wrapper functions need to be reserved. Add the following code to the hot update module (or DHE assembly, but not in AOT assemblies):

```csharp

public static class PreserveDOTSReversePInvokeWrapper
{
[ReversePInvokeWrapperGeneration(100)]
[MonoPInvokeCallback(typeof(SystemBaseRegistry.ForwardingFunc))]
public static void ForwordMethod(IntPtr system, IntPtr state)
{

}
}


```

Change the number 100 in the code to an appropriate number, recommended to be 5-10 times the number of Unmanaged System types.

## Burst Related

Hot update functions containing [BurstCompile] have changed, remove the [BurstCompile] attribute, otherwise errors will occur during runtime. This issue may be optimized in the future.
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ Currently, there are three commercial versions, with specific feature comparison
| Supplementary Metadata |||||
| Incremental GC |||||
| Unity 2019-2022 LTS |||||
| [DOTS](./dots) |||||
| [Full Generic Sharing](./fullgenericsharing) | ||||
| [DOTS](./dots) | ||||
| [Metadata Optimization](./metadataoptimization.md) | ||||
| [Standard Interpretation Performance Optimization](./basicoptimization) | ||||
| [Offline Instruction Optimization](./advancedoptimization) | ||||
Expand Down
1 change: 0 additions & 1 deletion sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ const sidebars = {
'business/intro',
'business/differentialhybridexecution',
'business/fullgenericsharing',
'business/dots',
'business/metadataoptimization',
'business/basicoptimization',
'business/advancedoptimization',
Expand Down

0 comments on commit 3d23e46

Please sign in to comment.