使用恩智浦的i.MX RT1050跨界处理器和 ZEPHYRTM实时操作系统 的性能分析
一项基准测试研究,旨在了解相较于i.MX 6UL处理器上的 Linux BSP的性能优势
弗洛林·莱奥特斯库、马里乌斯·克里斯蒂安·弗拉德和迈克尔·C·布罗焦利
A.1 简介
软件和硬件性能分析对于嵌入式系统的评估与设计至关重要。此类分析有助于了解系统的局限性,识别性能瓶颈,并确定系统相较于其他设备的运行表现。性能分析可通过自定义的基准测试应用程序实现,这些程序执行特定算法,从而提供有关被测系统、设计及开发过程的性能统计数据。此类基准测试的示例包括SPEC CPU基准测试,其旨在提供可用于比较不同计算机系统上计算密集型工作负载的性能测量结果。EEMBC是另一组主要面向嵌入式计算的基准测试。EEMBC基准测试套件由具有共同兴趣的成员工作组开发,致力于为测量从物联网边缘节点到下一代高级驾驶辅助系统的嵌入式处理器实现的性能和能效建立明确定义的标准。
除了使用前面提到的标准化基准测试外,系统开发者通常还会选择实施微基准测试,以关注系统中非常小或关键的功能。虽然微基准测试并非用于表征更广泛的系统级性能,但在关注特定系统组件时,它可以成为一个非常有用的工具。例如,微基准测试可用于分析在特定系统中创建执行线程所需的时间。尽管这并不能表征整个系统的性能,也无法反映系统在特定目标应用负载下的性能,但它可以提供对系统特定方面的细粒度洞察。
然而,需要注意的是,基准测试和微基准测试的作用是有限的。许多嵌入式解决方案供应商并未公开其解决方案的底层硬件设计,也极少向系统用户开放其系统级软件或源代码。因此,在分析和比较不同系统之间的特性时,基准测试和微基准测试存在一定的局限性。
本节提供了一个实际案例,说明如何使用微基准测试对嵌入式系统设计中关键的软硬件解决方案进行分析。具体而言,通过定制微基准测试对基于 Arm® Cortex®‐M7 核心的恩智浦 i.MX RT1050 跨界处理器上运行的 Zephyr™操作系统与基于 Arm Cortex‐A7 核心的 NXP i.MX 6UL 应用处理器上运行的 Linux BSP 进行性能分析。该分析涵盖了多个系统组件,包括但不限于线程创建、互斥锁使用和内存分配,这些均为现代高性能嵌入式系统设计中的基本场景。
需要注意的是,Zephyr™操作系统(一种面向物联网的微型开源实时操作系统)与Linux(一种开源的类Unix单体内核操作系统)之间存在差异,因此这种比较并非完全“同类对比”。本研究旨在为嵌入式设计师提供一组典型的微基准测试,用于在执行相同任务时比较软硬件解决方案。读者或系统开发者需自行推断这些系统级任务与其整体目标应用之间的关联。为了评估两种方案之间的性能差异,特别开发了一些合成微基准测试,用于评估动态内存分配与释放、互斥锁加锁与解锁、线程创建、线程连接以及上下文切换所需的时间。
总之,本次性能分析的结果表明,Zephyr™操作系统(在 i.MX RT1050跨界处理器上运行)提高了整体系统响应能力,并最终降低了物联网和嵌入式系统开发成本。上述与Linux + i.MX 6UL解决方案相比,任务在Zephyr™操作系统 + i.MX RT1050解决方案上执行得更快。以下部分将解释得出该比较结果所采用的方法。
A.2 配置信息
研究中分析的第一个配置是恩智浦 i.MX RT1050。i.MX RT1050 是一款跨界处理器,结合了应用处理器的高性能和高度集成性以及微控制器的易用性和实时功能。i.MX RT1050 在 600 MHz 频率下运行 Arm® Cortex®‐M7 核心。
该器件完全受恩智浦的MCUXpresso 软件和工具支持,这是一套全面且连贯的免费软件开发工具,适用于Kinets、LPC和i.MX RT微控制器。MCUXpresso SDK还包含适用于Keil MDK和IAR Embedded Workbench for Arm的项目文件。
配置 #1 还包括 ZEPHYRTM 操作系统。ZEPHYRTM 是一种用于互联的资源受限设备的小型实时可扩展操作系统,支持多种架构,并在 Apache 许可证 2.0 下发布。
A.2.1 配置 #1 概述:i.MX RT1050 配置—硬件和软件
- 开发板:MIMXRT1050‐EVK
- 处理器: MIMXRT1052DVL6A Arm® Cortex®‐M7 核心
- 核心数量:1
- 核心频率:600 MHz
- 电路板原理图: SCH‐29538 REV A1
- 操作系统名称: Zephyr操作系统
- 操作系统类型: 实时
本研究中分析的第二种配置是恩智浦 i.MX 6UL 硬件与 Linux 操作系统的组合。i.MX6 UltraLight 是一款高性能、高能效的处理器系列,在撰写本文时其 ARM A7 核心运行速度最高可达 696 MHz。i.MX6 UltraLite 应用处理器包含一个集成的电源管理模块,可降低外部电源的复杂性并简化电源时序。该系列中的每个处理器都提供多种内存接口,包括 16 位 LPDDR2、DDR3、DDR3L、原始和托管 NAND 闪存、NOR 闪存、eMMC、四线 SPI,以及用于连接外设(如无线局域网、蓝牙™、全球定位系统、显示屏和摄像头传感器)的多种其他接口。在 i.MX6 UL 上运行的软件为 Linux 板级支持包发布版本 Linux BSP ‐ 内核 4.9.88‐imx_4.9.88_2.0.0_ga。
如后文将详细讨论的,与第一种配置中的 ZEPHYRTM 操作系统不同,此版本并非 Linux 的实时版本。
A.2.2 配置 #2 概要:i.MX 6UL 配置
- 开发板: MCIMX6G2CVM05AB
- 处理器: i.MX6UL: i.MX 6UltraLite 处理器,基于 Arm Cortex‐A7 核心
- 核心数量:1
- 核心频率:528 MHz
- 电路板原理图: SCH‐29163 REV A2
- 操作系统名称: Linux BSP ‐ 内核 4.9.88‐imx_4.9.88_2.0.0_ga
- 操作系统类型: 非实时
A.3 分析范围
如引言中所述,本工作旨在评估并比较配备Zephyr™操作系统的i.MX RT1050 EVK与配备Linux BSP的i.MX 6UL EVK的性能。目标是确定配备嵌入式ARM SoC的MIMXRT1050‐EVK开发板与配备应用处理器的类似开发板之间可能存在的性能差距。由于i.MX 6UL EVK的中央处理器速度配置最接近i.MX RT1050 EVK,因此我们选择i.MX 6UL开发板进行最佳对比。
此外,选择 Zephyr™操作系统 而非其他实时操作系统,是因为它是免费的且功能全面,作为一个协作项目进行开发,并由活跃的开源社区提供支持。虽然 Zephyr™操作系统 和 Linux 操作系统 都可以表现出实时特性,但 Zephyr™操作系统 最初的设计目标是完全遵循传统 RTOS 原则,而 Linux 传统上主要用于桌面和服务器领域的较大工作负载。此外,在撰写本文时,Linux需要附加补丁才能符合传统 RTOS 原则。
为了获得可比较的结果,尽管已知存在操作系统差异,但仍重点使用了相同的应用程序外设接口(API)来进行本研究中所用的定制微基准测试。这些微基准测试使用 C 语言开发,并采用了 Pthreads API 库(POSIX API 库)。对于 Zephyr™操作系统,其可用的 API 版本为 POSIX PSE52,根据 Zephyr™ 社区文档,该版本仅对完整的 POSIX 规范提供部分支持。
微基准测试执行内存分配与释放、互斥锁加锁与解锁、线程创建、线程连接、上下文切换,并记录每个操作的耗时。
为了确定执行任务的耗时,我们在Linux + i.MX 6UL EVK解决方案中使用了POSIX clock_gettime()。对于在i.MX RT1050 EVK上运行的Zephyr™操作系统,我们则使用了TIMING_INFO_PRE_READ()函数,而不是clock_gettime()。由于ZephyrTM操作系统调度器的特性超出了本研究的范围,clock_gettime()函数生成的定时值不一致,而且由于ZEPHYRTM源代码也使用了TIMING_INFO_PRE_READ()函数,因此决定继续采用该方法。
A.3.1 微基准测试 #1:动态内存(堆)分配与释放基准
在C编程语言中,动态内存分配是指通过C标准库中的一组函数进行手动内存管理。C编程语言以静态、自动或动态方式管理内存。
静态变量与可执行代码一起分配在主存中,并在整个程序的生命周期内持续存在。自动管理的变量或局部变量在栈上分配,随着函数的调用和退出而创建和销毁。静态变量和局部变量的内存分配大小在编译时确定,变长数组除外。如果所需大小直到运行时才能确定(例如,从用户输入或磁盘文件读取任意大小的数据),则使用固定大小的数据对象是不够的。在这种情况下,动态内存分配解决了问题——内存通过更显式的方式进行管理,通常是在称为堆的大块自由空间中进行分配(图1)。
换句话说,堆是计算机的一个内存区域,在 C 语言的情况下由程序员手动管理。而在其他编程语言中,例如 Java,内存是自动管理的。
在 Linux 下的 C 语言中管理堆内存位置时,使用 malloc() 和 free() 函数(在 C++ 中还有 new() 和 delete() 函数)。malloc 函数用于在此内存中分配空间,而 free 用于释放该内存。在 Zephyr™操作系统 中,这些函数名为 k_malloc() 和 k_free(),其功能与 malloc() 和 free() 相同。本次分析围绕这些函数开发了微基准测试,并将其命名为堆_基准测试。目的是测量分配和释放堆内存所需的时间。在后台,该基准测试在1000次迭代的堆分配循环中分配4字节(int类型大小),然后通过第二个“堆释放”循环释放已分配的内存。对于Linux BSP,每次分配和释放循环的时间使用time_get_time()进行测量,这是一个基于clock_get_time()的封装函数。对于Zephyr™操作系统,则使用了TIMING_INFO_PRE_READ()函数。
在堆分配和堆释放循环结束时,计算了给定循环的最终平均分配和释放时间,如上面的源代码所示。
A.3.2 微基准测试#2:线程创建和连接基准测试
在计算机科学中,执行线程是一组可以由调度器独立管理的程序指令序列,此处的调度器是操作系统的一部分。线程和进程的实现因操作系统而异,但在大多数情况下,线程是进程的一个组成部分。一个进程内可存在多个线程,这些线程并发执行,并在线程之间共享资源(如内存),而不同的进程则不共享这些资源。特别是,一个进程的线程在其可执行代码以及任何时刻的变量值方面是共享的。图2 描绘了两个进程,每个进程拥有一个或多个线程。
在此比较中,进程是名为thread_bench的运行中的基准测试,它使用pthread_create() POSIX函数生成多个线程。该进程创建 2000个线程,并测量创建全部2000个线程所需的时间。在线程创建结束时,将记录的时间除以创建的线程数量,得到创建单个线程的平均时间。
该基准测试还使用pthread_join()函数来测量连接时间,该函数通过暂停父线程的执行使其与子线程同步,直到子线程终止。
A.3.3 微基准测试 #3:互斥锁锁定与解锁基准测试
在计算机科学中,互斥是一种并发控制方法,专门用于防止两个或多个线程之间的竞争条件。竞争条件是指系统的一种行为,其中两个独立的工作流正在修改一个共享资源,而该共享资源用于生成系统的输出。类比到现实世界,我们可以考虑两名机械师(两个线程)共同组装一台汽车发动机。他们并行地组装发动机,然而,某些子组件必须按照特定顺序进行组装,以确保发动机能正常工作。
每名机械师都有各自负责的发动机部分。为了确保组件按正确顺序安装,每名机械师在装配的关键段期间应对发动机的相关部分拥有独占所有权。这种独占所有权可与互斥锁相关联,其中互斥对象就是我们的汽车发动机。释放发动机可与释放互斥锁相关联。
互斥锁加锁与解锁基准测试,名为 mutex_bench,对这两个操作各测量 1000 次时间。最后,它计算对互斥变量进行加锁和解锁的平均时间。为了执行互斥锁的加锁与解锁,我们使用了 Pthread API 库中的 pthread_mutex_lock() 和 pthread_mutex_unlock()函数。
A.3.4 微基准测试#4:上下文切换基准测试
在计算中,上下文切换是存储进程或线程状态的过程,以便之后能够恢复该状态并从同一位置继续执行。这使得多个进程可以共享一个中央处理器,是多任务操作系统的一项基本特性。
“上下文切换”这一短语的确切含义在使用中存在显著差异。在多任务环境中,它指的是存储一个任务的系统状态,以便暂停该任务并恢复另一个任务的过程。上下文切换也可能由中断引发,例如当一个任务需要访问磁盘存储时,从而释放中央处理器时间以供其他任务使用。某些操作系统还需要通过上下文切换来在用户模式和内核模式任务之间进行切换。上下文切换过程可能对系统性能产生负面影响,尽管这种影响的程度取决于所执行切换的性质(图3)。
该基准测试通过创建两个线程,连续进行500,000次上下文切换来测量上下文切换时间。在上下文切换期间,基准测试记录经过的时间,然后将该时间除以上下文切换次数,从而得出每次上下文切换的平均时间。
A.4 分析结果
图4 和 5 包含了上述基准测试报告的分数。每个基准测试执行了三次迭代。可以看出,使用Zephyr™操作系统的结果是确定性的。每次在i.MX RT1050 EVK上运行Zephyr™操作系统的基准测试时,结果都相同(图4)。
在i.MX 6UL上运行Linux BSP时,每次运行的结果各不相同,与平均值的偏差最大达到9%(图5)。
下表重点列出了从这些基准测试迭代次数中计算出的平均时间。此处的平均时间以周期为单位进行计算(越低越好)。
根据这些数据,与在{i.MX 6UL EVK}上运行的Linux BSP相比, i.MX RT1050上的ZEPHYRTM操作系统在所有时间周期方面均表现出显著改进。更具体地说,本节中详述的微基准测试向系统开发人员表明,i.MX RT1050上的ZEPHYRTM操作系统在堆分配、互斥锁使用、线程创建和连接时间以及上下文切换方面提供了关键的性能改进。正如大多数嵌入式解决方案开发者所了解的,这些通常 是整体解决方案和系统级应用设计与实现中的关键构建模块。
| OS |
Zephyr™操作系统
1.11.99 |
Linux BSP
4.9.88‐imx_4.9.88_2.0.0_ga | 差值(作为倍数) |
|---|---|---|---|
| 板名称 | i.MX RT1050 EVK | i.MX 6UL EVK | – |
| CPU核心 | 1 | 1 | – |
| 核心频率(MHz) | 600 | 528 | – |
| 平均堆内存分配时间(周期) | 1001 | 11,499 | 11x |
| 平均堆内存释放时间(周期) | 1126 | 4870 | 4x |
| 平均 pthread_mutex_lock 时间(周期) | 53 | 799 | 15x |
| 平均 pthread_mutex_unlock 时间(周期) | 83 | 818 | 10x |
| 平均 pthread_create 时间(周期) | 719 | 85,478 | 118x |
| 平均 pthread_join 时间(周期) | 1702 | 89,219 | 52x |
| 平均上下文切换时间(周期) | 47 | 1284 | 27x |
1800
1600
1400
1200
1001 1001 1126 1126
CP U cy cle s
堆内存释放时间 pthread_mutex_lock pthread_mutex_unlock
83 53 53 53 83 83
pthread_create
基准测试名称
719 719 719
1702
Zephyr OS 1.11.99 ‐ i.MX RT1050 EVK ‐ 1核@600兆赫兹
1702 1702
Run1 Run2
Run3
上下文切换时间 使用k_yield
pthread_join
47 47 47
堆内存分配时间
1126 1001 1000
800
600
400
200
0
100000
90000
80000
70000
60000
50000
40000
30000
20000 10912 12496
堆内存分配时间 堆内存释放时间 pthread_mutex_lock pthread_mutex_unlock
基准测试名称
C P U c yc le s
pthread_create pthread_join上下文切换时间
使用 sched_yield
1283 1284 1286
Run1
Run2 Run3
11088
85686 89206
81542
88993 84838
Linux BSP ‐ 内核 4.9.88‐imx_4.9.88_2.0.0_ga ‐ i.MX 6UL EVK ‐ 1核@528MHz
93825
4576 5104 4928
865 811 721 874 761 818 10000
0
A.5 摘要和结论
本节的主要贡献如下所述:
1. 通过在两种不同的软硬件解决方案上运行自定义微基准测试,完成了一项性能分析。
2. 基准测试基于通用API开发,以确保获得可比较的结果。
3. 使用了不同的函数来收集经过的时间:clock_gettime()用于Linux系统,TIMING_INFO_PRE_READ用于Zephyr™操作系统。
4. 与Linux BSP和i.MX 6UL相比,Zephyr™操作系统和i.MX RT1050 EVK具有以下优势:
a. 上下文切换速度快27倍。
b. 内存分配与释放速度快达11倍。
c. 使用pthread库进行互斥锁的加锁与解锁速度快达15倍。
d. 在线程的创建、合并与取消方面速度更快。
e. 能够在更低的成本下提供更优的性能。
5. Zephyr™操作系统与i.MX RT1050 EVK开发板相结合,提供了可预测的执行时间,使其能够应用于具有各种时间约束的场景。
总之,本节介绍了将基准测试和微基准测试作为嵌入式系统开发者工具箱中的又一工具。通过将战略性编写的微基准测试与其他系统级监控和指标收集相结合,嵌入式系统开发者可以深入了解特定解决方案内各种硬件和软件组件的性能,以及在特定市场中竞争性解决方案之间的性能差异。凭借优化和调优整体系统功能开发的能力,嵌入式系统开发者可以战略性地专注于产品和解决方案推向市场的开发和优化时间。此外,通过对多个系统使用相同的基准测试,系统架构师和应用开发者可以评估竞争性市场解决方案在硬件和软件能力方面的性能差异。通过这种方式,系统架构师和开发者可以选择适合其特定应用的硬件和软件解决方案。
305

被折叠的 条评论
为什么被折叠?



