SimSpace Weaver 的重要概念 - AWS SimSpace Weaver

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

SimSpace Weaver 的重要概念

模拟或游戏会受到运行它的计算机的限制。随着虚拟世界的规模不断扩大以及复杂性不断增加,处理性能会逐渐降低。计算时间会更长,系统内存更容易耗尽,客户端帧速率也会下降。对于不需要实时性能的模拟,这可能只会带来少许烦恼。但是,对于业务关键型应用场景,如果处理延迟增加,则会导致成本攀升。如果您的模拟或游戏需要实时性能,那么性能下降就必然会成为问题。

对于达到性能限制的模拟,常见的解决方案是采取简化措施。通常,用户数量众多的在线游戏会在不同的服务器上部署虚拟世界的副本并分散用户,从而解决扩展问题。

SimSpace Weaver 解决扩展问题的方法就是:在空间上划分虚拟世界,并将这些划分出来的部分分布在 AWS Cloud 中运行的计算实例集群上。计算实例协同工作,并行处理整个模拟世界。对其中的所有对象以及与其连接的所有客户端而言,您的模拟世界依然是一个单一的集成空间。您不必再因硬件性能限制而简化模拟,而是可以在云中添加更多计算容量。

SimSpace Weaver 的工作原理

您的模拟由一个包含许多对象的世界组成。有些对象(例如,人和车辆)会移动和做事情。其他对象(例如,树木和建筑物)是静态的。在 SimSpace Weaver 中,实体是模拟世界中的对象。

您可以定义模拟世界的边界,然后将其划分为网格。您不需要创建在整个网格上运行的模拟逻辑,而是可以创建在网格中的一个单元格上运行的模拟逻辑。在 SimSpace Weaver 中,空间应用程序是您编写的程序,用于实现网格单元格的模拟逻辑。这包括单元格中所有实体的逻辑。空间应用程序的所有权区域是空间应用程序控制的网格单元格。

注意

在 SimSpace Weaver 中,“应用程序”一词可以指应用程序的代码或该代码的运行实例。


                                    划分为一个二维网格的模拟世界地图
您的模拟世界划分为一个网格

您将模拟世界划分为一个网格。每个空间应用程序都为该网格中的单个单元格实现模拟逻辑。

SimSpace Weaver 为网格的每个单元格运行空间应用程序代码的实例。所有空间应用程序实例都并行运行。在本质上,SimSpace Weaver 将您的整体模拟划分为多个小模拟。每个小模拟都处理整个模拟世界的一部分。SimSpace Weaver 可在 AWS Cloud 中的多个 Amazon Elastic Compute Cloud (Amazon EC2) 实例(称为工作线程)上分布和运行这些小模拟。一个工作线程可运行多个空间应用程序。

实体可在模拟世界中移动。如果实体进入另一个空间应用程序的所有权区域(网格中的另一个单元格),则新区域的空间应用程序所有者将接管该实体的控制权。如果您的模拟在多个工作线程上运行,则实体可以从一个工作线程上的空间应用程序控制下移到另一个工作线程上的空间应用程序中。当实体移动到另一个工作线程上时,SimSpace Weaver 会处理底层网络通信。

订阅

空间应用程序在世界中的视图就是它的所有权区域。为了了解模拟世界中另一个部分正在发生的事件,空间应用程序创建了订阅订阅区域是整个模拟世界区域的子集。订阅区域可以包含多个所有权区域的部分,其中包括空间应用程序的所有权区域。SimSpace Weaver 将订阅区域内发生的所有实体事件(例如,进入、退出、创建、更新和删除)通知空间应用程序。


                                        仅有一个可观测单元格的世界网格
空间应用程序的世界视图

空间应用程序的世界视图就是其所有权区域,即世界网格中的一个单元格。


                                        包含一个可观测单元格和一个额外可观测区域的世界网格,这个额外区域格涵盖了另一个单元格及其部分周边单元格
增加了订阅区域的空间应用程序视图

空间应用程序使用订阅来了解模拟世界中另一个部分正在发生的事件。订阅区域可包含多个网格单元格和单元格部分。

例如,模拟实体进行物理交互的应用程序可能需要了解其所有权区域空间边界之外的实体。为此,应用程序可订阅与其所有权区域边界相接的区域。创建订阅后,应用程序会收到有关这些区域中实体事件的通知,并且可以读取实体。另一个例子是自动驾驶车辆,它需要看到前方 200 米内的所有实体,无论哪个应用程序拥有该区域。车辆应用程序可创建具有筛选器的订阅,该筛选器用于覆盖可视区域的轴对齐边界框 (AABB)。

您可以创建不负责管理模拟空间方面的模拟逻辑。自定义应用程序是在单个工作线程上运行的可执行程序。您可以控制自定义应用程序的生命周期(启动和停止)。模拟客户端可以连接到自定义应用程序来查看模拟或与之交互。您还可以创建在每个工作线程上运行的服务应用程序。SimSpace Weaver 会在运行模拟的每个工作线程上启动服务应用程序的一个实例。

自定义应用程序和服务应用程序创建订阅来了解实体事件和读取实体。这些应用程序没有所有权区域,因为它们不是空间应用程序。使用订阅是这些应用程序了解模拟世界中正在发生的事件的唯一途径。

如何使用 SimSpace Weaver

使用 SimSpace Weaver 时,您需要遵循以下主要步骤:

  1. 编写和构建集成 SimSpace Weaver 应用程序 SDK 的 C++ 应用程序。

    1. 您的应用程序调用 API 来与模拟状态进行交互。

  2. 编写客户端,通过某些应用程序查看您的模拟并与其交互。

  3. 在文本文件中配置模拟。

  4. 将您的应用程序包和模拟配置上传到服务。

  5. 启动模拟。

  6. 根据需要启动和停止您的自定义应用程序。

  7. 将客户端连接到您的自定义或服务应用程序,以便查看模拟或与其交互。

  8. 在 Amazon CloudWatch Logs 中查看模拟日志。

  9. 停止模拟。

  10. 清理模拟。

模拟架构

模拟架构(或简称架构)是一种 YAML 格式的文本文件,其中包含模拟的配置信息。SimSpace Weaver 在启动模拟时使用您的架构。SimSpace Weaver 应用程序 SDK 可分发程序包中包含了一个示例项目的架构。在创建自己的架构时,您可以将其作为起点。有关模拟架构的更多信息,请参阅 SimSpace Weaver 模拟架构参考

工作线程和资源单位

工作线程是运行模拟的 Amazon EC2 实例。您可以在模拟架构中指定工作线程类型。SimSpace Weaver 将您的工作线程类型映射到服务使用的特定 Amazon EC2 实例类型。SimSpace Weaver 为您启动和停止工作线程,并管理工作线程之间的网络通信。SimSpace Weaver 为每个模拟启动一组工作线程。不同的模拟使用不同的工作线程。

工作线程上的可用计算(处理器和内存)能力划分为称为计算资源单位(或简称资源单位)的逻辑单元。资源单位代表着固定数量的处理器和内存容量。

注意

我们之前将计算资源单位称为。在我们的文档中,您可能仍然会看到“槽”这个术语。

模拟时钟

每个模拟都有自己的时钟。您可以使用 API 调用或 SimSpace Weaver 控制台来启动和停止时钟。只有在时钟运行时,模拟才会更新。模拟中的所有操作都发生在称为刻度的时间段内。时钟会向所有工作线程公告每个刻度的开始时间。

时钟率(或刻度率)是时钟公告的每秒刻度数量(赫兹或 Hz)。模拟所需的时钟率是模拟架构的一部分。针对刻度的所有操作都必须先完成,然后才能开始下一个刻度。因此,生效的时钟率可能低于所需的时钟率。生效的时钟率不会高于所需的时钟率。

分区

分区是工作线程上的一段共享内存。每个分区都包含部分模拟状态数据。

空间应用程序的分区(也称为空间应用程序分区空间分区)包含空间应用程序所有权区域中的所有实体。SimSpace Weaver 根据每个实体的空间位置将实体放在空间应用程序分区中。这意味着 SimSpace Weaver 会尝试将空间上彼此邻近的实体放在同一个工作线程上。这样,在模拟应用程序拥有的实体时,可以最大限度减少应用程序对其不拥有的实体所需的知识量。

State Fabric

State Fabric 是所有工作线程上的共享内存(所有分区的集合)的系统。它会保存模拟的所有状态数据。

State Fabric 使用自定义二进制格式,将实体描述为该实体的每个数据字段的一组初始数据和更新日志。凭借这种格式,您可以访问实体在模拟时间前一点的状态,并将其映射回现实世界时间中的某个点。缓冲区的大小是有限的,它不可能回溯到缓冲区之外的时间。SimSpace Weaver 在更新日志中为每个字段使用指向当前偏移量的指针,并在字段更新过程中更新指针。SimSpace Weaver 使用共享内存将这些更新日志映射到应用程序的进程空间。

这种对象格式可降低开销并且没有序列化成本。SimSpace Weaver 还使用此对象格式来解析和识别索引字段(例如,实体位置)。

实体

实体是模拟中的最小数据构建基块。实体的示例包括角色(例如,人和车辆)和静态对象(例如,建筑物和障碍物)。实体具有可作为永久数据存储在 SimSpace Weaver 中的属性(例如,位置和方向)。实体存在于分区中。

应用程序

SimSpace Weaver 应用程序是您编写的软件,其中包含运行每个模拟刻度的自定义逻辑。大多数应用程序的目的是在模拟运行时更新实体。您的应用程序调用 SimSpace Weaver 应用程序 SDK 中的 API 来对模拟中的实体执行操作(例如,读取和更新)。

您可以将应用程序及其所需资源(例如,库)打包为 .zip 文件,然后将其上传到 SimSpace Weaver。应用程序在工作线程上的 Docker 容器中运行。SimSpace Weaver 为每个应用程序分配固定数量的资源单位。

SimSpace Weaver 为每个应用程序分配一个(且只有一个)分区的所有权。应用程序及其分区位于同一个工作线程上。每个分区只有一个应用程序所有者。应用程序可以在其分区中创建、读取、更新和删除实体。应用程序拥有其分区中的所有实体。

共有三种类型的应用程序:空间应用程序自定义应用程序服务应用程序。它们因使用案例和生命周期而异。

注意

在 SimSpace Weaver 中,“应用程序”一词可以指应用程序的代码或该代码的运行实例。

空间应用程序

空间应用程序会更新模拟中空间上存在的实体的状态。例如,您可以定义一个 Physics 应用程序,该应用程序负责根据实体的速度、形状和大小在每个刻度中移动和碰撞实体。在这种情况下,SimSpace Weaver 会并行运行 Physics 应用程序的多个实例来处理工作负载的大小。

SimSpace Weaver 管理空间应用程序的生命周期。您可以在模拟架构中指定空间应用程序分区的排布。当您启动模拟时,SimSpace Weaver 会为每个空间应用程序分区启动一个空间应用程序。当您停止模拟时,SimSpace Weaver 会关闭您的空间应用程序。

其他类型的应用程序可以创建实体,但只有空间应用程序可以更新实体。其他类型的应用程序必须将其创建的实体转移到空间域中。SimSpace Weaver 使用实体的空间位置将实体移动到空间应用程序的分区中。这会将实体的所有权转移给空间应用程序。

自定义应用程序

您可以使用自定义应用程序来与模拟进行交互。自定义应用程序使用订阅读取实体数据。自定义应用程序可以创建实体。但是,应用程序必须将实体转移给空间应用程序,才能将该实体包含在模拟中并进行更新。您可以让 SimSpace Weaver 为自定义应用程序分配网络端点。模拟客户端可连接到网络端点来与模拟进行交互。您可以在模拟架构中定义自定义应用程序,但由您负责启动和停止它们(使用 SimSpace Weaver API 调用)。在工作线程上启动自定义应用程序实例后,SimSpace Weaver 不会将该实例转移给其他工作线程。

服务应用程序

当您需要在每个工作线程上运行只读进程时,您可以使用服务应用程序。例如,如果您有一个大型模拟,并且需要一个查看客户端,该客户端可在模拟中移动,并且仅向用户显示可见实体,则可以使用服务应用程序。在这种情况下,单个自定义应用程序实例无法处理模拟中的所有实体。您可以将服务应用程序配置为在每个工作线程上启动。然后,其中的每一个服务应用程序都可以筛选分配给它的工作线程上的实体,并且仅将相关实体发送给与其连接的客户端。然后,当它在模拟空间中移动时,您的查看客户端可以连接到不同的服务应用程序。您可以在模拟架构中配置服务应用程序。SimSpace Weaver 会为您启动和停止服务应用程序。

应用程序摘要

下表总结了不同类型的 SimSpace Weaver 应用程序的特征。

  空间应用程序 自定义应用程序 服务应用程序
读取实体

更新实体

创建实体

是*

是*

生命周期

托管(由 SimSpace Weaver 控制。)

非托管(由您控制。)

托管(由 SimSpace Weaver 控制。)

启动方法

SimSpace Weaver 按照您在架构中指定的方式,为每个空间分区启动一个应用程序实例。

您启动每个应用程序实例。

SimSpace Weaver 按照架构中指定的方式,在每个工作线程上启动一个或多个应用程序实例。

客户端可以连接

* 当自定义应用程序或服务应用程序创建实体时,该应用程序必须将实体的所有权转移给空间应用程序,以便空间应用程序更新实体的状态。

SimSpace Weaver 是运行相同的可执行应用程序代码,并且具有相同启动选项和命令的应用程序实例的集合。我们按域所包含的应用程序类型来对域进行分类:空间域、自定义域和服务域。您可以在域中配置应用程序。

订阅和复制

应用程序会创建对空间区域的订阅,从而了解区域中的实体事件(例如,进入、退出、创建、更新和删除)。应用程序会先处理订阅中的实体事件,然后读取它不拥有的分区中实体的数据。

分区可以与应用程序位于同一个工作线程上(这称为本地分区),但该分区可以归另一个应用程序拥有。分区也可以存在于其他工作线程上(这称为远程分区)。如果订阅的是远程分区,则工作线程通过称为复制的过程来创建远程分区的本地副本。然后,工作线程会读取本地副本(复制的远程分区)。如果工作线程上的另一个应用程序需要在同一个刻度上从该分区读取,则该工作线程会读取相同的本地副本。