了解openEuler系统环境
查看系统信息
基本的系统架构不必多说,可以使用uname查看:
值得一提的是lscpu的结果,它可以让我们查看特定于鲲鹏处理器的一些性质:
这个命令对于喜欢硬件的人士还是很有用的。我们可以展开聊聊它内容的意义:
其中NUMA对我来说比较新鲜。在计算机体系结构中,我见到的通常的结构是UMA,CPU和内存之间通过共用的总线连接,彼此没有差别。但是NUMA会将每个插槽的CPU分别分配内存,访问自己的内存是直接访问,而访问其他内存区域需要经过其他CPU来间接访问,出现可用但时间略长的结果,有更好的本地内存表现。
观察C语言char数据类型
用于检验的简短程序如下所示。这个程序主要展示 char、signed char 和 unsigned char 在类型转换和补码表示下的行为差异。
输出内容为:
可以看到在鲲鹏架构下gcc编译时,将默认的char视为unsigned char。这与x86下的gcc表现是不同的,后者会将char视为signed char。当然,如果通过gcc的编译参数改变编译的默认行为,可以将二者统一为相同的行为。
体验aarch64架构精简指令集
利用objdump显示一段简单代码的汇编,简单代码是这样的:
生成的汇编是这样的:
可以看到产生的指令都是统一32位长度的等长指令,而且命令中都是常见的汇编指令,这和鲲鹏RISC指令集的定位相符。
不过,我实际是使用的反汇编代码时混合显示源代码的形式:
利用gcc -g生成调试信息、利用objdump -S将汇编指令与对应的 C 源代码交叉显示。但实际生成的反汇编没有这样的混合视图,这可能是鲲鹏架构下的gcc支持尚不完善导致的。
后记
这次主要是初步探索ARM架构。之前其实用过ARM架构的开发板,交叉编译还是很让人头疼的。这次或许可以尝试一下ARM架构的服务器在使用上会不会有什么大的差别,尤其是基于比较特殊的鲲鹏处理器。期待进一步的探索!
了解openEuler系统环境
查看系统信息
基本的系统架构不必多说,可以使用uname查看:
值得一提的是lscpu的结果,它可以让我们查看特定于鲲鹏处理器的一些性质:
➜ ~ lscpu Architecture: aarch64 CPU op-mode(s): 64-bit Byte Order: Little Endian CPU(s): 1 On-line CPU(s) list: 0 Vendor ID: HiSilicon BIOS Vendor ID: QEMU Model name: Kunpeng-920 BIOS Model name: 1.0 Model: 0 Thread(s) per core: 1 Core(s) per socket: 1 Socket(s): 1 Stepping: 0x1 Frequency boost: disabled CPU max MHz: 2400.0000 CPU min MHz: 2400.0000 BogoMIPS: 200.00 Flags: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm j scvt fcma dcpop asimddp asimdfhm Caches (sum of all): L1d: 64 KiB (1 instance) L1i: 64 KiB (1 instance) L2: 512 KiB (1 instance) L3: 32 MiB (1 instance) NUMA: NUMA node(s): 1 NUMA node0 CPU(s): 0 Vulnerabilities: Gather data sampling: Not affected Itlb multihit: Not affected L1tf: Not affected Mds: Not affected Meltdown: Not affected Mmio stale data: Not affected Retbleed: Not affected Spec store bypass: Vulnerable Spectre v1: Mitigation; __user pointer sanitization Spectre v2: Not affected Srbds: Not affected Tsx async abort: Not affected这个命令对于喜欢硬件的人士还是很有用的。我们可以展开聊聊它内容的意义:
Architecture: aarch64
CPU 架构为 aarch64(64 位 ARM 架构)。
CPU 仅支持 64 位操作模式。
数据存储为小端序(低位字节在前)。
CPU(s): 1
逻辑 CPU 总数为 1。
Vendor ID: HiSilicon
CPU 实际厂商为华为海思(HiSilicon)。
BIOS 报告的厂商为 QEMU(可能运行在虚拟化环境中)。
CPU 型号为鲲鹏 920(海思基于 ARMv8 的服务器芯片)。
BIOS 报告的型号版本为 1.0。
内部模型编号(通常无实际意义)。
CPU 修订版本号(步进值)。
每个物理核心支持 1 个线程(无超线程)。
每个 CPU 插槽(Socket)有 1 个物理核心。
CPU 插槽数量为 1(单路系统)。
动态调频(如 Turbo Boost)已禁用。
CPU 最大频率为 2400 MHz(2.4 GHz)。
CPU 最小频率固定为 2400 MHz(无动态降频)。
Linux 内核计算的虚拟性能指标(用于粗略比较,非实际性能)。
Caches (sum of all)
1 个 L1 数据缓存,大小 64 KB。
1 个 L1 指令缓存,大小 64 KB。
1 个 L2 缓存,大小 512 KB。
1 个 L3 缓存,大小 32 MB。
NUMA 架构,非统一内存访问
非统一内存访问(NUMA)节点数为 1(单节点系统)。
NUMA 节点 0 包含逻辑 CPU 0。
其中NUMA对我来说比较新鲜。在计算机体系结构中,我见到的通常的结构是UMA,CPU和内存之间通过共用的总线连接,彼此没有差别。但是NUMA会将每个插槽的CPU分别分配内存,访问自己的内存是直接访问,而访问其他内存区域需要经过其他CPU来间接访问,出现可用但时间略长的结果,有更好的本地内存表现。
观察C语言char数据类型
用于检验的简短程序如下所示。这个程序主要展示 char、signed char 和 unsigned char 在类型转换和补码表示下的行为差异。
// // ch.c // gcc thisfile // // The default type of char is 'unsigned char' in the Kunpeng platform. // // gcc thisfile in both x86 and Kunpeng architecture. And try to // gcc -fsigned-char thisfile in Kunpeng architecture. And try to // gcc -funsigned-char thisfile in x86 architecture // #include <stdio.h> // positive or non positive, is a problem #define PNP(x) \ ((x) < 0 ? printf("negative") : \ ((x) == 0) ? printf("zero") : \ printf("positive")) int main() { // original code of 1: 0000 0001b // ones' complement of 1: 1111 1110b // two's complement of -1: 1111 1111b char ch = -1; printf("sizeof ch is %zu, %zu, %zu, %zu\n\n", sizeof(char), sizeof(ch), sizeof(signed char), sizeof(unsigned char)); printf(" char ch = %2xh, %+4d, ", ch & 0xff, ch); PNP(ch); printf("\n\n"); printf(" signed char ch = %2xh, %+4d, ", (signed char)ch & 0xff, (signed char)ch); PNP((signed char)ch); printf("\n"); printf("unsigned char ch = %2xh, %+4d, ", (unsigned char)ch & 0xff, (unsigned char)ch); PNP((unsigned char)ch); printf("\n"); return 0; }输出内容为:
➜ gcc ./char.o sizeof ch is 1, 1, 1, 1 char ch = ffh, +255, positive signed char ch = ffh, -1, negative unsigned char ch = ffh, +255, positive可以看到在鲲鹏架构下gcc编译时,将默认的char视为unsigned char。这与x86下的gcc表现是不同的,后者会将char视为signed char。当然,如果通过gcc的编译参数改变编译的默认行为,可以将二者统一为相同的行为。
体验aarch64架构精简指令集
利用objdump显示一段简单代码的汇编,简单代码是这样的:
// abc.c // // gcc -g abc.c // objdump -S ./a.out // int main() { int a = 1; int b = 2; int c = a + b; return a+b+c; }生成的汇编是这样的:
可以看到产生的指令都是统一32位长度的等长指令,而且命令中都是常见的汇编指令,这和鲲鹏RISC指令集的定位相符。
不过,我实际是使用的反汇编代码时混合显示源代码的形式:
利用gcc -g生成调试信息、利用objdump -S将汇编指令与对应的 C 源代码交叉显示。但实际生成的反汇编没有这样的混合视图,这可能是鲲鹏架构下的gcc支持尚不完善导致的。
后记
这次主要是初步探索ARM架构。之前其实用过ARM架构的开发板,交叉编译还是很让人头疼的。这次或许可以尝试一下ARM架构的服务器在使用上会不会有什么大的差别,尤其是基于比较特殊的鲲鹏处理器。期待进一步的探索!