Microarchitecture Analysis
Based on Arm performance monitor unit (PMU) events, you can learn the running status of instructions on the CPU pipeline. You can modify your application accordingly to make full use of your hardware resources.
Command Function
Analyzes the running status of instructions on the CPU pipeline based on Arm PMU events, helping quickly locate performance bottlenecks of the current application on the CPUs.
Syntax
1 | devkit tuner top-down [-h] [-c {n | n,m | n-m}] [-d <sec>] [-D <sec>] [-l {0, 1, 2, 3}] [-L {0, 1, 2, 3, 4, 5, 6}] [-i <sec>] [-p {PID | PID1,PID2 | ALL}] [-r {user, kernel, all}] [-G cgroup_name] [workload workload...] |
devkit tuner top-down [workload workload...] can be used to collect data of a specified application. Replace [workload workload...] in the command with the application path and application parameter. Only one of -c, -p, -G, and the application parameter can be specified.
Parameter Description
Parameter |
Option |
Description |
|---|---|---|
-h/--help |
- |
(Optional) Obtains help information. |
-c/--cpu |
- |
(Optional) Numbers of CPU cores to be collected, for example, 0, 0,1,2, and 0-2. By default, all CPU cores are collected. |
-d/--duration |
- |
(Optional) Collection duration, in seconds. The minimum value is 1 second. By default collection never ends. You can press Ctrl+\ to cancel the task or press Ctrl+C to stop the collection and start analysis. |
-D/--delay |
- |
(Optional) Collection delay, which defaults to 0, in seconds, and must be less than the collection duration. |
-l/--log-level |
0/1/2/3 |
(Optional) Log level, which defaults to 1.
|
-L/--profile-level |
0/1/2/3/4/5/6 |
(Optional) Analysis metric, which defaults to 0.
|
-i/--interval |
- |
(Optional) Collection interval, which defaults to 1, in seconds. If the collection duration is set, the collection interval must be less than or equal to the configured collection duration. |
-p/--pid |
- |
(Optional) ID of a process to be collected. Separate multiple PIDs with commas (,). |
-r/--collection-range |
user/kernel/all |
(Optional) Process collection level. When -p/--pid is set to ALL, the option user or kernel can be selected, which means that user-mode processes or kernel-mode processes can be collected. The default value is all, which collects user-mode and kernel-mode performance data.
|
-G/--cgroup |
- |
Monitors the specified process group and manages its resources. Only cgroup v1 and cgroup v2 are supported. |
Example
- Collect CPU data.
1devkit tuner top-down -c 0-127 -d 3 -L 2
The -c 0-127 parameter indicates that CPU cores 0 to 127 are collected. The -d 3 parameter indicates that the collection duration is 3 seconds. The -L 2 parameter indicates that the Back-End Bound -> Core Bound instruction data is collected.
Command output:
================================================================================ Version : DevKit xxx CPU Model : xxx Command : devkit tuner top-down -c 0-127 -d 3 -L 2 ================================================================================ TOP-DOWN Summary Report-ALL Time:2026/08/17 11:07:14 ================================================================================ Top-down metrics of CPU(s) 0-127: Cycles 22,120,459,894 Instructions 6,577,304,096 IPC 0.30 -------------------------------------------------------------------------------- Top-down Metrics Bound(%) Preferred Sampling Event -------------------------------------------------------------------------------- Bad Speculation 0.74 -- Frontend Bound 24.21 -- Retiring 4.96 inst_retired Backend Bound 70.09 -- +-- Core Bound 39.81 -- | +-- FDIV Stall 0.00 -- | +-- DIV Stall 0.02 -- | +-- FSU Stall 0.01 -- | +-- Resource Bound* 6.93 -- | | +-- Rob_stall* 3.69 -- | | +-- Ptag_stall* 1.84 -- | | +-- MapQ_stall* 1.36 -- | | +-- PCBuf_stall* 0.03 -- | | `-- Other_stall* 0.00 -- | `-- Exe Ports Util 32.86 -- | +-- 0 ports serialize 10.68 -- | +-- 0 ports non serialize 11.30 -- | +-- 1 ports 5.15 -- | +-- 2 ports 2.75 -- | +-- 3 ports 1.41 -- | +-- 4 ports 0.71 -- | +-- 5 ports 0.45 -- | `-- 6p ports 0.39 -- `-- Memory Bound 30.28 -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- PMU Event Count -------------------------------------------------------------------------------- r0008 6,577,304,096 r0011 22,120,459,894 r001b 7,563,467,111 r2004 1,784,843,805 r2005 16,592,828 r2006 889,524,233 r2007 3,720 r2008 182,819 r2009 0 r200a 0 r200b 651,403,354 r200c 64 r200d 6,662,957 r2011 32,134,809,261 r7000 2,396,695,506 r7001 20,035,587,561 r7002 12,646 r7003 6,218,209 r7004 2,208,588 r7005 8,655,118,761 r7006 227,458 r700a 6,976,499,310 r700b 7,385,778,572 r700c 3,365,958,196 r700d 1,799,326,407 r700e 923,350,966 r700f 466,977,934 r7010 297,269,510 r7011 257,489,500 -------------------------------------------------------------------------------- 3014 milliseconds time elapsed Metrics marked with '*' indicate approximate values. Note: To view the hotspot data. You can run devkit tuner hotspot -e [Preferred Sampling Event]
- Collect process IDs.
1devkit tuner top-down -p 3716829 -d 3
The -p 3716829 parameter indicates that the process with PID 3716829 is collected. The -d 3 parameter indicates that the collection duration is 3 seconds. If the -L parameter is not specified, data of all dimensions is collected.
Command output:
================================================================================ Version : DevKit xxx CPU Model : xxx Command : devkit tuner top-down -p 3716829 -d 3 ================================================================================ TOP-DOWN Summary Report-ALL Time:2026/08/17 11:18:02 ================================================================================ Top-down metrics of process id '3716829': Cycles 8,625,186,702 Instructions 10,457,232,945 IPC 1.21 -------------------------------------------------------------------------------- Top-down Metrics Bound(%) Preferred Sampling Event -------------------------------------------------------------------------------- Bad Speculation 3.63 -- +-- Branch Mispredicts 2.03 br_mis_pred | +-- Indirect Branch 0.05 -- | +-- Push Branch 0.00 -- | +-- Pop Branch 0.01 -- | `-- Other Branch 1.98 -- `-- Machine Clears 1.60 -- +-- Nuke Flush 0.07 -- `-- Other Flush 1.53 -- Frontend Bound 5.84 -- +-- Fetch Latency Bound 1.83 -- | +-- ITLB Miss 0.05 -- | +-- ICache Miss 0.04 -- | +-- BP_Misp_Flush 0.62 br_mis_pred | +-- OoO Flush 0.88 -- | `-- Static Predictor Flush 0.24 -- `-- Fetch Bandwidth Bound 4.01 -- Retiring 20.21 inst_retired Backend Bound 70.32 -- +-- Core Bound 57.43 -- | +-- FDIV Stall 0.00 -- | +-- DIV Stall 0.00 -- | +-- FSU Stall 0.00 -- | +-- Resource Bound* 5.60 -- | | +-- Rob_stall* 0.08 -- | | +-- Ptag_stall* 4.28 -- | | +-- MapQ_stall* 1.20 -- | | +-- PCBuf_stall* 0.04 -- | | `-- Other_stall* 0.00 -- | `-- Exe Ports Util 51.83 -- | +-- 0 ports serialize 1.55 -- | +-- 0 ports non serialize 10.24 -- | +-- 1 ports 7.35 -- | +-- 2 ports 7.60 -- | +-- 3 ports 7.84 -- | +-- 4 ports 7.13 -- | +-- 5 ports 5.21 -- | `-- 6p ports 4.92 -- `-- Memory Bound 12.89 -- +-- L1 Bound 12.79 -- | +-- DTLB 0.02 -- | +-- Misalign 0.52 -- | +-- Resource Full 0.00 -- | +-- Instruction Type 5.52 -- | +-- Forward hazard 5.25 -- | +-- Structure hazard 1.48 -- | `-- Pipeline 0.01 -- +-- L2 Bound 0.07 -- | +-- buffer pending 0.00 -- | +-- snoop pending 0.00 -- | +-- Arb idle 0.06 -- | `-- Pipeline 0.00 -- +-- L3 or DRAM Bound 0.03 -- `-- Store Bound 0.00 -- +-- SCA 0.00 -- +-- Head 0.00 -- +-- Order 0.00 -- `-- Other 0.00 -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- PMU Event Count -------------------------------------------------------------------------------- r0008 10,457,232,945 r0010 25,439,300 r0011 8,625,186,702 r001b 12,335,725,513 r0027 499,769 r0028 3,139 r002e 22,599 r0030 503,199 r100d 132,306 r1010 592,534 r1013 408 r1016 1,984 r104f 9,590,169 r2004 37,507,258 r2005 19,360,817 r2006 2,000,749,226 r2007 174,310 r2008 0 r2009 0 r200a 0 r200b 563,573,940 r200c 0 r200d 3,619 r200f 889,328 r2010 19,964,722 r2011 3,022,358,507 r2012 157,484,970 r5090 664,645 r5091 22,376,269 r5092 0 r5093 238,219,339 r5094 226,335,535 r5095 63,837,928 r5096 263,307 r50a0 354,500,058 r50a2 120,465,149 r50a3 5,602,771,261 r50a4 320,041,963 r7000 686,650,792 r7001 7,779,503,393 r7002 0 r7003 39,639 r7004 0 r7005 1,426,145,480 r7006 0 r7007 10,913,329 r7008 3,597,779 r700a 255,574,360 r700b 1,691,083,605 r700c 1,213,399,236 r700d 1,254,830,245 r700e 1,294,985,046 r700f 1,177,759,552 r7010 860,792,684 r7011 812,094,133 r701e 100 r701f 148,816 r7020 6,967,299 -------------------------------------------------------------------------------- 3000 milliseconds time elapsed Metrics marked with '*' indicate approximate values. Note: To view the hotspot data. You can run devkit tuner hotspot -e [Preferred Sampling Event] Optimization Suggestions 1. The percentage of Backend Bound is high.(Threshold: 20.00%) Take the following optimization measures for C/C++ applications compiled using the BiSheng compiler. For other compilers, you can refer to the optimization suggestions. Verify the optimization suggestions in your specific application scenario. (1) Use the jemalloc library. Associate the libjemalloc.so soft link in the lib directory of the BiSheng compiler with the jemalloc dynamic library entity whose size is the same as the system page table size in this directory, and add the -ljemalloc parameter for the compilation. (2) Set Wrap-memset/memcpy: Wl,-wrap=memset/memcpy -lstringlib. The BiSheng compiler provides memset/memcpy implementation in the libstring library, which is more adaptable to the AArch64 architecture. When the glibc version is earlier and the function proportion is high, the performance is significantly improved. (3) Set prefetch to save the data to be accessed to the cache, so as to reduce the value of d-cache miss. The hardware has its own prefetch mechanism. The compiler supports the software prefetch function. When tsv110 is enabled, the BiSheng compiler automatically enables software prefetch. You can adjust the prefetch density by using the three parameters: -mllvm -prefetch-loop-depth=x -mllvm -min-prefetch-stride=y -mllvm -prefetch-distance=z, where for example, x=3, y=9, z=940. (4) Add the -fstack-arrays parameter to place all arrays onto the stack. The parameter takes effect only on Fortran. (5) Try enabling huge pages.
Preferred Sampling Event displays key events that affect the microarchitecture binding. You can optimize the binding effect by tuning key events. You can use devkit tuner hotspot -e [Preferred Sampling Event] for the analysis and tuning.
- Collect application data.
1devkit tuner top-down -d 10 -L 2 /opt/testdemo/cache_miss_long
The -d 10 parameter indicates that the collection duration is 10 seconds, and the -L 2 parameter indicates that the Back-End Bound -> Core Bound instruction data is collected.
Command output:
================================================================================ Version : DevKit xxx CPU Model : xxx Command : devkit tuner top-down -d 10 -L 2 /opt/testdemo/cache_miss_long ================================================================================ the thread1 id is -1356948064 the thread2 id is -1358958304 TOP-DOWN Summary Report-ALL Time:2026/08/17 11:22:12 ================================================================================ Top-down metrics of /opt/testdemo/cache_miss_long: Cycles 55,292,272,017 Instructions 40,145,547,063 IPC 0.73 -------------------------------------------------------------------------------- Top-down Metrics Bound(%) Preferred Sampling Event -------------------------------------------------------------------------------- Bad Speculation 5.48 -- Frontend Bound 10.10 -- Retiring 12.10 inst_retired Backend Bound 72.32 -- +-- Core Bound 26.51 -- | +-- FDIV Stall 0.00 -- | +-- DIV Stall 0.00 -- | +-- FSU Stall 0.00 -- | +-- Resource Bound* 15.38 -- | | +-- Rob_stall* 2.73 -- | | +-- Ptag_stall* 10.27 -- | | +-- MapQ_stall* 2.37 -- | | +-- PCBuf_stall* 0.00 -- | | `-- Other_stall* 0.00 -- | `-- Exe Ports Util 11.13 -- | +-- 0 ports serialize 0.49 -- | +-- 0 ports non serialize 7.44 -- | +-- 1 ports 0.82 -- | +-- 2 ports 0.71 -- | +-- 3 ports 0.58 -- | +-- 4 ports 0.51 -- | +-- 5 ports 0.28 -- | `-- 6p ports 0.31 -- `-- Memory Bound 45.81 -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- PMU Event Count -------------------------------------------------------------------------------- r0008 40,145,547,063 r0011 55,292,272,017 r001b 58,322,433,170 r2004 6,460,821,996 r2005 596,401 r2006 24,272,902,416 r2007 4,771,304 r2008 0 r2009 0 r200a 0 r200b 5,606,240,337 r200c 0 r200d 220,768 r2011 33,522,108,179 r7000 27,205,809,141 r7001 53,736,982,585 r7002 0 r7003 1,088,367 r7004 0 r7005 34,039,890,312 r7006 0 r700a 2,447,679,257 r700b 37,026,341,328 r700c 4,093,648,117 r700d 3,520,247,123 r700e 2,907,983,082 r700f 2,525,107,827 r7010 1,376,298,342 r7011 1,519,648,641 -------------------------------------------------------------------------------- 10000 milliseconds time elapsed Metrics marked with '*' indicate approximate values. Note: To view the hotspot data. You can run devkit tuner hotspot -e [Preferred Sampling Event] Optimization Suggestions 1. The percentage of Backend Bound is high.(Threshold: 20.00%) Take the following optimization measures for C/C++ applications compiled using the BiSheng compiler. For other compilers, you can refer to the optimization suggestions. Verify the optimization suggestions in your specific application scenario. (1) Use the jemalloc library. Associate the libjemalloc.so soft link in the lib directory of the BiSheng compiler with the jemalloc dynamic library entity whose size is the same as the system page table size in this directory, and add the -ljemalloc parameter for the compilation. (2) Set Wrap-memset/memcpy: Wl,-wrap=memset/memcpy -lstringlib. The BiSheng compiler provides memset/memcpy implementation in the libstring library, which is more adaptable to the AArch64 architecture. When the glibc version is earlier and the function proportion is high, the performance is significantly improved. (3) Set prefetch to save the data to be accessed to the cache, so as to reduce the value of d-cache miss. The hardware has its own prefetch mechanism. The compiler supports the software prefetch function. When tsv110 is enabled, the BiSheng compiler automatically enables software prefetch. You can adjust the prefetch density by using the three parameters: -mllvm -prefetch-loop-depth=x -mllvm -min-prefetch-stride=y -mllvm -prefetch-distance=z, where for example, x=3, y=9, z=940. (4) Add the -fstack-arrays parameter to place all arrays onto the stack. The parameter takes effect only on Fortran. (5) Try enabling huge pages. - Collect cgroup data.
1devkit tuner top-down -d 10 -L 2 -G my_test_cgroup
-d 10 indicates that the collection duration is 10 seconds. -L 2 indicates that the Back-End Bound->Core Bound instruction data is collected. -G my_test_cgroup indicates that the cgroup named my_test_cgroup is collected.
Command output:
================================================================================ Version : DevKit xxx CPU Model : xxx Command : devkit tuner top-down -d 10 -L 2 -G my_test_cgroup ================================================================================ TOP-DOWN Summary Report-ALL Time:2026/08/17 11:25:08 ================================================================================ Top-down metrics of cgroup: my_test_cgroup: Cycles 2,391,734,724 Instructions 926,312,370 IPC 0.39 -------------------------------------------------------------------------------- Top-down Metrics Bound(%) Preferred Sampling Event -------------------------------------------------------------------------------- Bad Speculation 3.95 -- Frontend Bound 0.00 -- Retiring 6.45 inst_retired Backend Bound 89.59 -- +-- Core Bound 0.00 -- | +-- FDIV Stall 0.00 -- | +-- DIV Stall 0.00 -- | +-- FSU Stall 0.00 -- | +-- Resource Bound* 0.00 -- | | +-- Rob_stall* 0.00 -- | | +-- Ptag_stall* 0.00 -- | | +-- MapQ_stall* 0.00 -- | | +-- PCBuf_stall* 0.00 -- | | `-- Other_stall* 0.00 -- | `-- Exe Ports Util 0.00 -- | +-- 0 ports serialize 0.00 -- | +-- 0 ports non serialize 0.00 -- | +-- 1 ports 0.00 -- | +-- 2 ports 0.00 -- | +-- 3 ports 0.00 -- | +-- 4 ports 0.00 -- | +-- 5 ports 0.00 -- | `-- 6p ports 0.00 -- `-- Memory Bound 89.59 -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- PMU Event Count -------------------------------------------------------------------------------- r0008 926,312,370 r0011 2,391,734,724 r001b 1,493,619,010 r2004 258,080,056 r2005 870,982 r2006 353,648,052 r2007 4,130 r2008 0 r2009 0 r200a 0 r200b 18,503,319 r200c 0 r200d 0 r2011 0 r7000 0 r7001 0 r7002 0 r7003 0 r7004 0 r7005 0 r7006 0 r700a 0 r700b 0 r700c 0 r700d 0 r700e 0 r700f 0 r7010 0 r7011 0 -------------------------------------------------------------------------------- 10019 milliseconds time elapsed Metrics marked with '*' indicate approximate values. Note: To view the hotspot data. You can run devkit tuner hotspot -e [Preferred Sampling Event]