该系列文章有4篇:
本文已同步至:
个人博客:itwakeup.com
微信公众号:vpp与dpdk研习社(vpp_dpdk_lab)
在src/vppinfra/test/
目录下,有许多通过REGISTER_TEST
注册的单元测试,用于对vppinfra
基础库做单元测试(功能、性能)。
程序主函数入口:src/vppinfra/test/test.c
执行make build
生成可执行文件test_infra
test_infra
运行参数说明:
将自动检测当前设备支持的CPU架构,一次运行可能会在多个架构下执行,例如:
1)执行所有单元测试:
[root@localhost vpp]# ./build-root/build-vpp_debug-native/vpp/bin/test_infra
Multiarch Variant: default
-------------------------------------------------------
clib_toeplitz_hash_x4 PASS
clib_toeplitz_hash PASS
clib_hmac_sha512 PASS
clib_hmac_sha384 PASS
clib_hmac_sha256 PASS
clib_hmac_sha224 PASS
clib_memcpy_x86_64 PASS
clib_mask_compare_u64 PASS
clib_mask_compare_u32 PASS
clib_mask_compare_u16 PASS
clib_ip_csum PASS
clib_index_to_ptr_u32 PASS
clib_crc32c PASS
clib_count_equal_u64 PASS
clib_count_equal_u32 PASS
clib_count_equal_u16 PASS
clib_count_equal_u8 PASS
clib_compress_u8 PASS
clib_compress_u16 PASS
clib_compress_u32 PASS
clib_compress_u64 PASS
clib_array_mask_u32 PASS
clib_poly1305 PASS
2)执行过滤后的单元测试:
[root@localhost vpp]# ./build-root/build-vpp_debug-native/vpp/bin/test_infra filter toeplitz
Multiarch Variant: default
-------------------------------------------------------
clib_toeplitz_hash_x4 PASS
clib_toeplitz_hash PASS
filter通过字符串过滤,这里filter toeplitz
和clib_toeplitz_hash
效果是一样的。
[root@localhost vpp]# ./build-root/build-vpp_debug-native/vpp/bin/test_infra perf
Warming up...
Multiarch Variant: default
-------------------------------------------------------
clib_toeplitz_hash_x4 Ops Freq IPC Clks Clks/Op Inst Inst/Op Brnch Brnch/Op BrMiss BrMiss/Op
fixed (per 12 byte tuple) 1024 .6 .56 463324 452.46 258566 252.51 331 .32 538972736 1372926791
fixed (per 12 byte tuple) 1024 .6 .58 446397 435.93 258566 252.51 10 0.00 538969600 1372926791
fixed (per 12 byte tuple) 1024 .6 .58 446905 436.43 258566 252.51 4 0.00 538969600 1372926791
fixed (per 36 byte tuple) 1024 .7 .52 1487815 1452.94 771591 753.51 1144 1.12 538986752 1372926791
fixed (per 36 byte tuple) 1024 .7 .52 1472341 1437.83 771590 753.51 523 .51 538986752 1372926791
fixed (per 36 byte tuple) 1024 .7 .53 1467644 1433.25 771591 753.51 529 .52 538986752 1372926791
variable size (per byte) 16384 .6 .56 608770 37.16 342027 20.88 36 0.00 538995072 8580792449
variable size (per byte) 16384 .6 .56 607568 37.08 342027 20.88 3 0.00 539003392 8580792450
variable size (per byte) 16384 .6 .56 607557 37.08 342027 20.88 2 0.00 539007552 8580792450
clib_toeplitz_hash Ops Freq IPC Clks Clks/Op Inst Inst/Op Brnch Brnch/Op BrMiss BrMiss/Op
fixed (per 12 byte tuple) 1024 .6 .62 712284 695.59 444423 434.01 145 .14 538979392 1372926791
fixed (per 12 byte tuple) 1024 .6 .63 707777 691.19 444422 434.01 9 0.00 538979392 1372926791
fixed (per 12 byte tuple) 1024 .6 .63 707428 690.85 444422 434.01 2 0.00 538981120 1372926791
fixed (per 36 byte tuple) 1024 .7 .59 2235202 2182.81 1316871 1286.01 3184 3.11 538981120 1372926791
fixed (per 36 byte tuple) 1024 .7 .59 2214148 2162.25 1316871 1286.01 3081 3.01 538981120 1372926791
fixed (per 36 byte tuple) 1024 .7 .59 2210284 2158.48 1316870 1286.01 3074 3.00 538981120 1372926791
variable size (per byte) 16384 .6 .62 931972 56.88 581644 35.50 6 0.00 539007552 8580792450
variable size (per byte) 16384 .6 .62 931700 56.87 581643 35.50 3 0.00 539024000 8580792451
variable size (per byte) 16384 .6 .62 931741 56.87 581644 35.50 7 0.00 539040448 8580792452
注:
bundle core-power
使用了Intel 特定的性能计数器,由于我的物理机是AMD处理器,会导致测试程序错误,因此仅测试bundle default
。bundle default
使用了以下PERF_COUNT,并不是所有CPU都支持,可以根据情况注释掉部分功能,注意和n_events一起修改。repeat
默认值为3,从测试报告可以看出每个性能测试都执行了3次。列名 | 解释 |
---|---|
Ops | 每次测试执行的操作数,例如 |
Freq | 频率标志位,通常是占用 CPU 总频率的比例 |
IPC | 每周期执行指令数 (Instructions Per Cycle),衡量 CPU 使用效率,越高越好 |
Clks | 总共消耗的 CPU 周期数 (clock cycles),越少越好 |
Clks/Op | 每次操作平均使用的 CPU 周期数,越低越好(<font style="background-color:#FBDE28;">这是关键的性能指标</font>) |
Inst | 执行的总指令数 |
Inst/Op | 每次操作的平均指令数,越低越好,但可能与函数复杂度有关 |
Brnch | 总分支指令数 |
Brnch/Op | 每次操作的平均分支数 |
BrMiss | 分支预测失败总数(Branch Mispredictions) |
BrMiss/Op | 每次操作的分支预测失败数,越低越好 |
clib_perfmon_init_by_bundle_name: perf_event_open[1]: No such file or directory
这个错误的根本原因是:内核中的 **perf_event**
功能未启用或所需的文件系统未挂载。
1)查看是否已经挂载:
mount | grep debugfs
mount | grep tracefs
如果未输出,可以执行:
mount -t debugfs none /sys/kernel/debug
mount -t tracefs none /sys/kernel/tracing
2)确保 /proc/sys/kernel/perf_event_paranoid
有访问权限
如果你不是在特权模式下运行,perf_event
可能被限制,查看perf_event_paranoid限制:
echo 1 > /proc/sys/kernel/perf_event_paranoid
参数说明:
数值 | 含义 |
---|---|
| 不做任何限制。任何用户都可以访问所有的性能事件,包括内核空间事件(极度不安全,建议仅用于调试)。 |
| 允许非特权用户访问用户空间和内核空间的性能计数器事件。可以进行完整的 |
| 默认值(在大多数发行版中)。允许访问用户空间的事件,但禁止访问内核空间事件(比如上下文切换、系统调用等)。 |
| 只允许 root 用户访问 perf 事件,其他用户无法使用 perf 工具。 |
| 禁止所有非 root 用户使用 perf,包括用户空间事件。这是最严格的设置,可能用于高安全性环境。 |
3)检查内核是否支持 perf_event
确认你的 Linux 内核编译时启用了 CONFIG_PERF_EVENTS
,预期:CONFIG_PERF_EVENTS=y
root@localhost vpp (interface-adaptive) # grep PERF_EVENTS /boot/config-$(uname -r)
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_GUEST_PERF_EVENTS=y
CONFIG_PERF_EVENTS=y
CONFIG_PERF_EVENTS_INTEL_UNCORE=m
CONFIG_PERF_EVENTS_INTEL_RAPL=m
CONFIG_PERF_EVENTS_INTEL_CSTATE=m
CONFIG_PERF_EVENTS_AMD_POWER=m
CONFIG_PERF_EVENTS_AMD_UNCORE=y
CONFIG_PERF_EVENTS_AMD_BRS=y
CONFIG_HAVE_PERF_EVENTS_NMI=y
CONFIG_INTEL_IOMMU_PERF_EVENTS=y
检查是否支持 perf_event_open
系统调用,预期能看到perf_event_open
root@localhost vpp (interface-adaptive) # grep perf_event_open /proc/kallsyms
ffffffffb4516010 T __pfx_bpf_lsm_perf_event_open
ffffffffb4516020 T bpf_lsm_perf_event_open
ffffffffb4529840 t __pfx___do_sys_perf_event_open
ffffffffb4529850 t __do_sys_perf_event_open
ffffffffb452a420 T __pfx___x64_sys_perf_event_open
ffffffffb452a430 T __x64_sys_perf_event_open
ffffffffb452a450 T __pfx___ia32_sys_perf_event_open
ffffffffb452a460 T __ia32_sys_perf_event_open
ffffffffb4742460 T __pfx_security_perf_event_open
ffffffffb4742470 T security_perf_event_open
ffffffffb47454e0 t __pfx_selinux_perf_event_open
ffffffffb47454f0 t selinux_perf_event_open
ffffffffb5e99908 r __BTF_ID__func__bpf_lsm_perf_event_open__810402
ffffffffb645e9a0 d event_exit__perf_event_open
ffffffffb645ea40 d event_enter__perf_event_open
ffffffffb645eae0 d __syscall_meta__perf_event_open
ffffffffb645eb20 d args__perf_event_open
ffffffffb645eb60 d types__perf_event_open
ffffffffb6d1d0e0 d __event_exit__perf_event_open
ffffffffb6d1d0e8 d __event_enter__perf_event_open
ffffffffb6d20298 d __p_syscall_meta__perf_event_open
ffffffffb6d229c0 d _eil_addr___ia32_sys_perf_event_open
ffffffffb6d229d0 d _eil_addr___x64_sys_perf_event_open
检查perf是否能够访问硬件性能事件
[root@localhost vpp]# perf stat -e cycles,instructions sleep 1
Performance counter stats for 'sleep 1':
1216136 cycles
1277627 instructions # 1.05 insn per cycle
1.000951723 seconds time elapsed
0.001012000 seconds user
0.000000000 seconds sys
如果出现<not supported>,可能的原因:
4)考虑注释掉不支持的perf参数
如果以上方法都不行,考虑注释掉不支持的perf参数。比如我测试时报错perf_event_open[1]: No such file or directory
,把config[1] = PERF_COUNT_HW_REF_CPU_CYCLES
去掉,记得同时将n_events
减1,修改后:
CLIB_PERFMON_BUNDLE (default) = {
.name = "default",
.desc = "IPC, Clocks/Operatiom, Instr/Operation, Branch Total & Miss",
.type = PERF_TYPE_HARDWARE,
.config[0] = PERF_COUNT_HW_CPU_CYCLES,
.config[1] = PERF_COUNT_HW_INSTRUCTIONS,
.config[2] = PERF_COUNT_HW_BRANCH_INSTRUCTIONS,
.config[3] = PERF_COUNT_HW_BRANCH_MISSES,
.n_events = 4,
.format_fn = format_perfmon_bundle_default,
.column_headers = CLIB_STRING_ARRAY ("Freq", "IPC", "Clks", "Clks/Op",
"Inst", "Inst/Op", "Brnch", "Brnch/Op",
"BrMiss", "BrMiss/Op"),
};
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。