AMP共享内存数据库
现代 SoC 平台通常采用异构远程处理器设备,并以不对称多处理(AMP)的方式运行。其中,恩智浦(NXP)的 i.MX 8 QuadMax 和 i.MX 8 QuadPlus 系列备受认可,它们配备了不同数量的 ARM® Cortex®-A 和 Cortex-M CPU 核心。此外,意法半导体(STM)的 STM32MP157F 设备也广受欢迎,它结合了双核 ARM® Cortex®-A7 和 Cortex®-M4 32 位精简指令集核心。
这种异构多核架构的优势在于,它可以将关键的硬实时任务交给 Cortex-M 处理器处理,从而实现极低延迟,而 Cortex-A 内核则专注于高性能任务。不同的 CPU 通常会运行不同的操作系统实例,例如,在 A 核心上运行 Linux,而在 M 核心上运行实时操作系统(如 FreeRTOS、MICROSAR 等)。
AMP 硬件中的共享内存区域可以直接访问,使得各个“集群”(即能够独立执行指令并运行独立操作系统的多个核心)之间可以进行通信和消息传递。传统上,共享内存主要用于通信,但随着应用程序复杂性和关键性的增加,尤其是使用 i.MX8 硬件时,Cortex-A 和 Cortex-M 核心之间也可以共享实时数据。
在 AMP 系统中,存储子系统有两种常见的组织方式:
客户端 - 服务器模式:数据库存放在单个集群的进程中,并由该进程独占访问。其他进程可以通过共享内存发送“消息”给“服务器”进程,从而间接访问数据。
共享内存数据库:存储库直接保存在设备的共享内存中,所有集群的进程/应用程序都可以直接访问。这种方式对数据驱动型应用特别有吸引力,因为它不仅提高了性能,还充分利用了整个 DDR 内存作为存储设备。通过精细调整竞争解决机制,多个线程可以从多个集群灵活地管理数据库访问。此外,由于没有单点故障(如服务器进程),这对安全关键系统尤为重要。
SmartEDB RT 实现了 AMP 共享内存数据库的方法,带来了以下优势:
- 更高的性能,得益于直接访问存储
- 针对多线程应用的精细调优的竞争解决机制
- 消除了单点故障的风险
如何使用 AMP 共享数据库与实时 API
AMP 共享内存数据库存储由 MCO_MEMORY_AMP 内存设备以及 mco_device_t::dev 联合体中的相应元素来描述。
struct {
unsigned int flags;
char *address;
char *hint;
} amp;
其中:
- 地址是共享内存段的物理地址,用于确保两个不同操作系统指向同一内存。
- 提示是操作系统应尝试映射该物理内存段的虚拟地址。对于数据库在 DPTR 模式下正确工作,这是必要的;否则可设为 0。
- 标志:0 或 MCO_RT_AMP_SHM_NONCACHE。后者禁用 CPU 缓存(如果可能),通常会影响性能。默认情况下,缓存保持开启,SmartEDB RT 在事务开始和结束时会无效化缓存以维护数据完整性,这对长事务有利。对于短事务,禁用缓存(通过 MCO_RT_AMP_SHM_NONCACHE)可能是更好的选择。
重要提示:若禁用缓存且无硬件管理的缓存一致性,必须将 MCO_DB_AMP_CACHE_SYNC 添加到 mco_db_params_t::mode_mask 中,以确保缓存无效化。
特定于操作系统的组件
与 SMP 系统不同,AMP 集群由不同的操作系统控制。因此,从集群间数据共享的角度来看,AMP 系统可以被视为一种分布式网络,在这种网络中,“节点”通过共享内存相互通信。由此可知,需要一种机制来同步对元数据结构的访问,从而同步共享存储,且这种机制独立于每个节点的操作系统。我们将这种机制称为分布式信号量。分布式信号量是控制在运行于 Cortex-M 内核之上的实时操作系统和运行于 Cortex-A 上的 Linux 之上的多个任务同步的组件。
在 Linux 系统中,分布式信号量是通过内核模块实现的。将工作目录更改为 target/sal/sync/rpmsg_sem/,调整 makefile 以设置正确的内核源代码和交叉编译器路径,然后运行“make”来构建模块。通过“insmod mco_rpmsg_sem.ko”加载该模块。
在 FreeRTOS 中,分布式信号量是通过库 rpmsg_lite 实现的。应当将其链接进来。
示例
请参阅 samples/amp