目录
简介
这篇指南描述如何入门并使用Arm指令模拟器(Arm Instruction Emulator, ArmIE)。Arm指令模拟器是一款跑在AArch64(也就是Arm64)平台上的软件工具,用来模拟SVE(Scalable Vector Extension)指令集。想了解SVE可以去看看,我翻译的另一篇《SVE(Scalable Vector Extension)简介》。Arm指令模拟器使你可以在没有SVE支持的硬件上跑编译好的SVE应用的二进制程序。
开始
本节介绍如何安装和开始使用 Arm® 指令仿真器。
Arm 指令仿真器 (armie) 是一个仿真器,可在任何基于 Armv8-A 的 AArch64 平台上运行,并模拟可扩展向量扩展 (SVE) 指令。 Arm 指令仿真器让您无需访问支持 SVE 的硬件即可开发 SVE 代码。
安装ARMIE
安装之前
确保Environment Modules或者Lmod Environment Modules system已经在你的机子上安装。关于如何安装Environment Modules的信息,可以参考Arm Alinea Studio environment configuration documentation文档。
安装步骤
- 下载合适你Linux主机平台的Arm指令模拟器包。可以在Arm Instruction Emulator 下载页下载指令模拟器。
- 提取下载好的包:
将tar -xvzf <package_name>.tar.gz
<package_name>
替换为下载包的全名。 - 可以进入到提取的包目录下查看文件:
cd <package_name>
- 以特权用户身份运行安装脚本:
其中sudo ./arm-instruction-emulator-22.0*_aarch64-linux-rpm.sh <option> <option>
<option>
是指安装脚本所支持的选项。支持的选项包括:
-a, --accept
自动接受 EULA(EULA 仍然显示)。【译者注:End User License Agreement (EULA) ,最终用户许可协议】
-i, --install-to <location>
安装到给定目录,如果你没有sudo权限安装到/opt/arm
或其他非用户目录,可以使用这个选项。
-f, --force
强制对非空目录进行安装尝试。
-h, --help
在终端中以帮助消息的形式显示此表。
如果没有应用选项,那么你将执行一个默认的安装,安装包会被解包到/opt/arm/<package_name>
。如果你使用-i
(或者--install-to
)选项指定一个自定义的安装路径,例如<install-dir>
:
那么安装包将会被安装到./<package_name>.sh --install-to <install_dir>
<install_dir>
。注意
如果你使用了--install-to
选项,则需要手动使其他用户可以使用安装和模块文件(如果他们需要)。
【译者注】我理解就是添加其他用户的权限,使得其他用户也可以有使用和访问的权限。 - 除非您包含
-a
(或--accept
)选项,否则安装程序会显示 EULA 并提示您同意这些条款。 要同意,请在提示符下键入“yes”。 有关发行内容的更多信息,请参阅位于<install-dir>/<package_name>
目录中的发行说明。
安装之后
ARMIE安装成功之后,接下来需要:
- 配置你的Linux环境:
- 要查看系统上可用的环境模块,请运行:
module avail
- 如果你没有看到ARMIE的环境模块,请配置
MODULEPATH
环境变量,把ARMIE安装路径添加进去:
然后再次坚持一下系统上是否有可用的环境模块:export MODULEPATH=$MODULEPATH:<install-dir>/modulefiles/
module avail
- 为系统中的处理器和您正在使用的编译器加载适当的 Arm 指令仿真器模块:
其中,module load armie<major-version>/<package-version>
<package-version>
是<major-version>.<minor-version>{.<patch-version>}.
。例如:
Tip:把module load 命令加入你的module load armie22/22.0
.profile
中,每次登陆即可自动加载 - 检查你的
PATH
环境变量,它应该包含来自<install-dir>/
的 Arm 指令仿真器bin
目录:echo $PATH /opt/arm/arm-instruction-emulator-22.0_Generic-AArch64_RHEL-8_aarch64-linux/bin64:...
- 要查看系统上可用的环境模块,请运行:
- 要学习如何使用Arm指令模拟器,可以去查阅 Get started with Arm Instruction Emulator.
- 有关 Arm 提供的服务器套件和高性能计算 (HPC) 工具使用的环境变量的信息,请参阅环境变量参考主题。
- 要卸载ARMIE,执行位于
<install-dir>/arm-instruction-emulator-<version>_<microarch>_<OS>-<OS_Version>_aarch64-linux/uninstall.sh
的uninstall.sh
脚本。
开始使用ARM 指令模拟器
这篇教程用了几组简单示例来说明如何编译SVE代码以及如何使用 Arm® 指令仿真器运行生成的二进制文件。
开始之前
- 本次任务使用Arm Compiler for Linux(Arm Allinea Studio的一部分)作为编译器。另外,你也可以使用GCC作为编译器。如果你想使用Arm Compiler for Linux,下载并安装适用你的平台的Arm Compiler for Linux。
- 加载适用你平台的ArmIE模块。
module load armie<major-version>/<package-version>
步骤
- 编译你的源代码,生成一个可执行的二进制文件
- 用ARMIE执行二进制。选择下面任意一种方式:
- 激活ARMIE,并指定要使用的向量长度:
armie -msve-vector-bits=<length> ./<binary>
- 使用检测 (-i) 或仿真 (-e) 客户端调用 Arm 指令仿真器,并指定要使用的向量长度:
检测和仿真客户端使您能够提取有关执行二进制文件的数据。armie -msve-vector-bits=<arg> -e <emulation_client> -i <instrumentation_client> -- ./<binary>
- 激活ARMIE,并指定要使用的向量长度:
示例:编译并执行一个“Hello World”程序
在这个例子中,你将用C写一个简单的“Hello World”程序,并用Arm Compiler for Linux编译,然后使用ARMIE执行。这个例子并不包含SVE代码。
- 加载适用于你平台的Arm Compiler for Linux。
其中,module load acfl/<package-version>
<package-version>
是<major-version>.<minor-version>{.<patch-version>}
。例如:module load acfl22/22.0
- 创建一个简单的Hello World程序,并将其保存到
hello.c
文件里。/* Hello World */ #include <stdio.h> int main() { printf("Hello World\n"); return 0; }
- 为了生成一个可执行二进制,用Arm C/C++ 编译器编译你的程序。
armclang -O3 -march=armv8-a+sve -o hello hello.c
-O3
选项开启最高级别优化,确保自动向量化被开启。-march=armv8-a+sve
选项定位目标硬件为Armv8-A架构,并在可执行二进制中生成SVE指令。注意
在这个例子中,没有使用SVE代码。但是,在编译要使用 Arm 指令仿真器运行的任何代码时,最好启用最高级别的自动矢量化并以支持 SVE 的架构为目标。 - 使用Arm指令模拟器执行生成的二进制
hello
。
这将返回:armie -msve-vector-bits=256 ./hello
对于这个简单的Hello World例子,Arm指令模拟器在支持SVE的架构里跑没有SVE指令的代码。要充分发挥 Arm 指令仿真器的潜力,即仿真 SVE 指令,我们必须研究一个更复杂的应用程序。 本教程的下一部分提供了一个包含 SVE 代码的应用程序示例。Hello World
示例:编译,向量化和执行有SVE代码的程序
- 加载适用于你平台的Arm Compiler for Linux。
其中,module load acfl/<package-version>
<package-version>
是<major-version>.<minor-version>{.<patch-version>}
。例如:module load acfl22/22.0
- 创建一个叫
example.c
,包含以下代码:
这段C代码用两个数组减去相应的元素,并将结果写入到第三个数组中。这三个数组使用// example.c #include <stdio.h> #include <stdlib.h> #define ARRAYSIZE 1024 int a[ARRAYSIZE]; int b[ARRAYSIZE]; int c[ARRAYSIZE]; void subtract_arrays(int *restrict a, int *restrict b, int *restrict c) { for (int i = 0; i < ARRAYSIZE; i++) { a[i] = b[i] - c[i]; } } int main() { for (int i = 0; i < ARRAYSIZE; i++) { // Generate a random number between 200 and 300 b[i] = (rand() % 100) + 200; // Generate a random number between 0 and 100 c[i] = rand() % 100; } subtract_arrays(a, b, c); printf("i \ta[i] \tb[i] \tc[i] \n"); printf("=============================\n"); for (int i = 0; i < ARRAYSIZE; i++) { printf("%d \t%d \t%d \t%d\n", i, a[i], b[i], c[i]); } }
restrict
关键字声明,它向编译器表明它们在内存中不重叠。 - 使用Arm C/C++编译器编译C代码。
armclang -O3 -march=armv8-a+sve -o example example.c
- 用Arm指令模拟器跑二进制。
这个程序最终返回:armie -msve-vector-bits=256 ./example
SVE架构扩展指定一个i a[i] b[i] c[i] ============================= 0 197 283 86 1 262 277 15 2 258 293 35 \... 1021 165 234 69 1022 232 295 63 1023 204 235 31
implemention defined
向量长度。msve-vector-bits
选项可以给Arm指令模拟器指定需要的向量长度。这个向量长度必须是128bits的倍数,最大不超过2048bits。你可以使用-mlist-vector-lengths
选项列出所有有效的向量长度。
返回:armie -mlist-vector-lengths
128 256 384 512 640 768 896 1024 1152 1280 1408 1536 1664 1792 1920 2048
下一步
了解如何使用 Arm 指令仿真器可用的仿真和仪器客户端分析您的应用程序,可以参阅Analyze Scalable Vector Extension (SVE) applications with Arm Instruction Emulator。
相关概念
- 疑难解答:Use -s
相关指南
相关信息
- Learn more about Arm Instruction Emulator
- DynamoRIO dynamic binary instrumentation tool platform
- DynamoRIO API
- DynamoRIO API Usage Tutorial
- Porting and Optimizing HPC Applications for Arm SVE guide
疑难解答:Use -s
介绍如何使用 -s
选项更好地了解 Arm® 指令仿真器使用的仿真命令和文件,以及在需要进一步帮助时向 Arm Support 发送什么内容。
-S
和--show-drrun-cmd
选项
为了展示 Arm Instruction Emulator 如何使用 DynamoRIO 的 drrun
命令来模拟和检测 SVE 二进制文件,请调用 -s
(或 --show-drrun-cmd
)选项。
例如,在以下命令行中,libsve_512.so
是 SVE 仿真客户端,libinscount_emulated.so
是检测客户端:
armie -s -msve-vector-bits=512 -i libinscount_emulated.so -- ./example_sve
将会返回:
/path/to/armie/bin64/drrun -client
/path/to/armie/lib64/release/libsve_512.so 0 "" -client
/path/to/armie/samples/bin64/libinscount_emulated.so 1 "" -max_bb_instrs 32 -max_trace_bbs 4 -- ./example_sve
Client inscount is running
. . .
-s
选项可让您了解 Arm 指令仿真器如何使用 DynamoRIO,并可用于将参数和调试选项传递给 DynamoRIO 的 drrun
命令。 例如,inscount 客户端有一个 -only_from_app
选项,它只计算应用程序指令并忽略库。 使用 drrun
命令传递 -only_from_app
选项:
/path/to/install/bin64/drrun -client
/path/to/install/lib64/release/libsve_512.so 0 "" -client
/path/to/install/samples/bin64/libinscount_emulated.so 1 "-only_from_app" -max_bb_instrs 32 -max_trace_bbs 4 -- ./example_sve
返回:
Client inscount is running
955 instructions executed of which 709 were SVE instructions
这表明应用程序使用了 955 条非 SVE 指令,而在计算库指令时为 118497 条。
将命令行参数传递给检测客户端的首选方法是使用 -a
或 --arg-iclient
选项。 有关详细信息,请参阅 armie 命令参考。 上述使用 drrun
命令的方法在同时需要检测客户端的命令行参数以及 DynamoRIO 的 drrun 命令的参数和调试选项的情况下很有用。
联系Arm Support
在程序崩溃的情况下,操作系统内核会创建一个核心转储文件。 此核心转储文件的位置和名称取决于系统的核心转储配置。 如果您的配置指定核心转储文件名包含崩溃二进制文件的名称,请注意这是被模拟的可执行文件的名称,而不是 Arm 指令模拟器二进制文件名称 (armie)。
核心转储文件应与 armie --version
的输出一起发送给 Arm 支持。 但是,如果您对核心转储文件中的敏感数据存在保密问题,请不要将核心转储发送给 Arm。 但是,如果没有核心转储文件,Arm 支持团队可能无法调查您的问题。
需求请求技术支持,请联系 Arm Support。
教程
在这部分,我们学习如何为Arm指令仿真器构建仪表客户端和自定义分析仪表,以及如何适用Arm指令仿真器分析你的SVE应用程序。
使用Arm指令仿真器分析SVE程序
介绍如何使用检测和仿真客户端以及如何使用 Arm® 指令仿真器运行您的应用程序。