Skip to content

Commit a4d06c6

Browse files
committed
Add Learning Path about tracking resource usage on WoA
Signed-off-by: Ruifeng Wang <[email protected]>
1 parent d336e4a commit a4d06c6

File tree

6 files changed

+392
-0
lines changed

6 files changed

+392
-0
lines changed

assets/contributors.csv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,5 @@ Ker Liu,,,,,
102102
Rui Chang,,,,,
103103
Alejandro Martinez Vicente,Arm,,,,
104104
Mohamad Najem,Arm,,,,
105+
Ruifeng Wang,Arm,,,,
106+
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
title: Track resource usage of applications on Windows on Arm
3+
4+
minutes_to_complete: 60
5+
6+
who_is_this_for: This is an introductory topic for developers who want to measure resource usage of applications on Windows on Arm devices.
7+
8+
learning_objectives:
9+
- Run video encode and decode tasks by using FFmpeg
10+
- Benchmark video encode task
11+
- Sample CPU / memory / power usage of video decode task
12+
13+
prerequisites:
14+
- A Windows on Arm computer such as the Lenovo Thinkpad X13s running Windows 11
15+
- Any code editor. [Visual Studio Code for Arm64](https://code.visualstudio.com/docs/?dv=win32arm64user) is suitable.
16+
17+
author: Ruifeng Wang
18+
19+
### Tags
20+
skilllevels: Introductory
21+
subjects: Migration to Arm
22+
armips:
23+
- Cortex-A
24+
tools_software_languages:
25+
- FFmpeg
26+
- PowerShell
27+
operatingsystems:
28+
- Windows
29+
30+
31+
32+
further_reading:
33+
- resource:
34+
title: Recording for Resource-based Analysis
35+
link: https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-8.1-and-8/hh448202(v=win.10)
36+
type: documentation
37+
- resource:
38+
title: Get started with Arm64EC
39+
link: https://learn.microsoft.com/en-us/windows/arm/arm64ec-build
40+
type: documentation
41+
- resource:
42+
title: Arm64EC - Build and port apps for native performance on Arm
43+
link: https://learn.microsoft.com/en-us/windows/arm/arm64ec
44+
type: documentation
45+
46+
47+
48+
### FIXED, DO NOT MODIFY
49+
# ================================================================================
50+
weight: 1 # _index.md always has weight of 1 to order correctly
51+
layout: "learningpathall" # All files under learning paths have this same wrapper
52+
learning_path_main_page: "yes" # This should be surfaced when looking for related content. Only set for _index.md of learning path content.
53+
---
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
# ================================================================================
3+
# FIXED, DO NOT MODIFY THIS FILE
4+
# ================================================================================
5+
weight: 21 # Set to always be larger than the content in this path to be at the end of the navigation.
6+
title: "Next Steps" # Always the same, html page title.
7+
layout: "learningpathall" # All files under learning paths have this same wrapper for Hugo processing.
8+
---
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
---
2+
title: Application and data set
3+
weight: 2
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
8+
9+
## Overview
10+
System resource usage provides an approach to understand the performance of an application as a black box. This Learning Path demonstrates how to sample system resource usage by using a script.
11+
12+
The application used is FFmpeg. It is a tool set that performs video encode and decode tasks. We will run the same tests with both x86_64 binary (through emulation) and Arm64 native binary.
13+
14+
## Application
15+
Binary builds are available. You don't need to build them from source. Download executable files for Windows:
16+
17+
1. Download [x86_64 package](https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2025-07-31-14-15/ffmpeg-n7.1.1-56-gc2184b65d2-win64-gpl-7.1.zip).
18+
2. Download [Arm64 native package](https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2025-07-31-14-15/ffmpeg-n7.1.1-56-gc2184b65d2-winarm64-gpl-7.1.zip).
19+
20+
Unzip the downloaded packages. You can find the binaries in **bin** folder. Note paths to **ffmpeg.exe** and **ffplay.exe**. They are used in later steps.
21+
22+
## Video source
23+
Download test video [RaceNight](https://ultravideo.fi/video/RaceNight_3840x2160_50fps_420_8bit_YUV_RAW.7z) from a public dataset. Unzip the package and note path to the uncompressed yuv file.
24+
25+
## Video encoding
26+
The downloaded video file is in yuv raw format. It means playback of the video file involves no decoding effort. You need to encode the raw video with some compressing algorithms to add computation pressure at playback.
27+
28+
Use **ffmpeg.exe** to compress the yuv raw video with x265 algorithm and convert file format to mp4. Open a terminal and run command:
29+
```console
30+
path\to\ffmpeg.exe -f rawvideo -pix_fmt yuv420p -s 3840x2160 -r 50 -i D:\path\to\RaceNight_YUV_RAW\RaceNight_3840x2160_50fps_8bit.yuv -vf scale=1920:1080 -c:v libx265 -preset medium -crf 20 D:\RaceNight_1080p.mp4 -benchmark -stats -report
31+
```
32+
33+
{{% notice Note %}}
34+
Modify the paths to `ffmpeg.exe` and yuv raw video file accordingly.
35+
{{% /notice %}}
36+
37+
The command transforms video size, compresses the video into a H.265 encoded mp4 file. `benchmark` option is turned on to show performance data at the same time. The generated file is at D:\RaceNight_1080p.mp4.
38+
39+
### View results
40+
Shown below is example output from running x86_64 version ffmpeg.exe:
41+
```output
42+
x265 [info]: tools: rd=3 psy-rd=2.00 early-skip rskip mode=1 signhide tmvp
43+
x265 [info]: tools: b-intra strong-intra-smoothing lslices=6 deblock sao
44+
Output #0, mp4, to 'D:\RaceNight_1080p.mp4':
45+
Metadata:
46+
encoder : Lavf61.7.100
47+
Stream #0:0: Video: hevc (hev1 / 0x31766568), yuv420p(tv, progressive), 1920x1080, q=2-31, 50 fps, 12800 tbn
48+
Metadata:
49+
encoder : Lavc61.19.101 libx265
50+
Side data:
51+
cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
52+
[out#0/mp4 @ 0000020e0d6f3880] video:13297KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:2KiB muxing overhead: 0.079970%
53+
frame= 600 fps=8.4 q=29.4 Lsize= 13308KiB time=00:00:11.96 bitrate=9115.2kbits/s speed=0.167x
54+
bench: utime=480.344s stime=10.203s rtime=71.548s
55+
bench: maxrss=910112KiB
56+
x265 [info]: frame I: 3, Avg QP:22.41 kb/s: 50202.13
57+
x265 [info]: frame P: 146, Avg QP:23.73 kb/s: 18265.18
58+
x265 [info]: frame B: 451, Avg QP:28.45 kb/s: 5827.62
59+
x265 [info]: Weighted P-Frames: Y:0.0% UV:0.0%
60+
61+
encoded 600 frames in 71.51s (8.39 fps), 9075.96 kb/s, Avg QP:27.27
62+
```
63+
64+
Example output from running Arm64 native ffmpeg.exe:
65+
```output
66+
x265 [info]: tools: rd=3 psy-rd=2.00 early-skip rskip mode=1 signhide tmvp
67+
x265 [info]: tools: b-intra strong-intra-smoothing lslices=6 deblock sao
68+
Output #0, mp4, to 'D:\RaceNight_1080p.mp4':
69+
Metadata:
70+
encoder : Lavf61.7.100
71+
Stream #0:0: Video: hevc (hev1 / 0x31766568), yuv420p(tv, progressive), 1920x1080, q=2-31, 50 fps, 12800 tbn
72+
Metadata:
73+
encoder : Lavc61.19.101 libx265
74+
Side data:
75+
cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
76+
[out#0/mp4 @ 000001b3c215f8e0] video:13348KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:2KiB muxing overhead: 0.080169%
77+
frame= 600 fps= 23 q=29.3 Lsize= 13359KiB time=00:00:11.96 bitrate=9150.2kbits/s speed=0.456x
78+
bench: utime=169.891s stime=7.281s rtime=26.224s
79+
bench: maxrss=1040836KiB
80+
x265 [info]: frame I: 3, Avg QP:22.40 kb/s: 50457.20
81+
x265 [info]: frame P: 146, Avg QP:23.71 kb/s: 18246.21
82+
x265 [info]: frame B: 451, Avg QP:28.40 kb/s: 5878.38
83+
x265 [info]: Weighted P-Frames: Y:0.0% UV:0.0%
84+
85+
encoded 600 frames in 26.20s (22.90 fps), 9110.78 kb/s, Avg QP:27.23
86+
```
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
---
2+
title: Tracking system resource
3+
weight: 3
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
8+
9+
## Sampling video decoding resource usage
10+
A PowerShell script does all the work. It launches the video decoding task, samples CPU and memory usage, and outputs sampled data to a file with format.
11+
12+
Open your code editor, copy content below and save it as `sample_decoding.ps1`.
13+
```PowerShell { line_numbers = true }
14+
param (
15+
[string]$exePath = "path\to\ffplay.exe",
16+
[string[]]$argList = @("-loop", "15", "-autoexit", "D:\RaceNight_1080p.mp4"),
17+
[int]$interval = 2,
18+
[string]$outputFile = "usage_log.csv"
19+
)
20+
21+
"" | Out-File -FilePath $outputFile
22+
23+
if (-Not (Test-Path $exePath)) {
24+
Write-Host "Executable not found at path: $exePath"
25+
exit 1
26+
}
27+
28+
$zoneIdentifier = "$exePath`:Zone.Identifier"
29+
if (Test-Path $zoneIdentifier) {
30+
Write-Host "exe is locked. Trying to unlock..."
31+
try {
32+
Unblock-File -Path $exePath
33+
Write-Host "Unlocked exe file."
34+
} catch {
35+
Write-Host "Failed to unlock exe: $($_.Exception.Message)"
36+
}
37+
} else {
38+
Write-Host "exe is not locked."
39+
}
40+
41+
try {
42+
$cmdLine = "`"$exePath`" $argList"
43+
Write-Host "Executing: $cmdLine"
44+
$process = Start-Process -FilePath $exePath -ArgumentList $argList -PassThru
45+
} catch {
46+
Write-Host "Failed to start process. Error: $_"
47+
exit 1
48+
}
49+
50+
$appPid = $process.Id
51+
Write-Host "Parent PID: $appPid"
52+
53+
Start-Sleep -Seconds 2
54+
$childProcess = Get-CimInstance -ClassName Win32_Process | Where-Object { $_.ParentProcessId -eq $appPid }
55+
56+
$index = 1
57+
$outHead = @()
58+
$outHead += "Timestamp,CPU Sum (s),Memory Sum (MB),Memory Private Sum (MB),CPU0 (s),Memory0 (MB),Memory Private0 (MB)"
59+
foreach ($child in $childProcess) {
60+
$childPid = $child.ProcessID
61+
Write-Host " - Child: $childPid"
62+
$outHead += "CPU$index (s),Memory$index (MB),Memory Private$index (MB)"
63+
$index++
64+
}
65+
$outHead -join "," | Out-File -Encoding utf8 $outputFile
66+
67+
Write-Host "Sampling start..."
68+
69+
while (-not $process.HasExited) {
70+
$cpu = @()
71+
$mem = @()
72+
$memPriv = @()
73+
$outLine = @()
74+
75+
$timestamp = Get-Date -Format o
76+
$outLine += $timestamp
77+
$proc = Get-Process -Id $appPid -ErrorAction SilentlyContinue
78+
if ($proc) {
79+
$cpu += $proc.CPU
80+
$mem += $proc.WorkingSet64 / 1MB
81+
$memPriv += $proc.PrivateMemorySize64 / 1MB
82+
83+
foreach ($child in $childProcess) {
84+
$procChild = Get-Process -Id $child.ProcessId -ErrorAction SilentlyContinue
85+
$cpu += $procChild.CPU
86+
$mem += $procChild.WorkingSet64 / 1MB
87+
$memPriv += $procChild.PrivateMemorySize64 / 1MB
88+
}
89+
90+
$outLine += ($cpu | Measure-Object -Sum).Sum
91+
$outLine += "{0:F2}" -f ($mem | Measure-Object -Sum).Sum
92+
$outLine += "{0:F2}" -f ($memPriv | Measure-Object -Sum).Sum
93+
for ($i = 0; $i -lt $cpu.Count; $i++) {
94+
$outLine += $cpu[$i]
95+
$outLine += $mem[$i]
96+
$outLine += $memPriv[$i]
97+
}
98+
99+
$outLine -join "," | Out-File -Append -Encoding utf8 $outputFile
100+
}
101+
102+
Start-Sleep -Seconds $interval
103+
$process.Refresh()
104+
}
105+
```
106+
107+
{{% notice Note %}}
108+
Modify the path to `ffplay.exe` on line 2 accordingly.
109+
{{% /notice %}}
110+
111+
Run the script:
112+
```console
113+
Set-ExecutionPolicy -Scope Process RemoteSigned
114+
.\sample_decoding.ps1
115+
```
116+
A video starts playing. It ends in 3 minutes. And then you can find the sample results file **usage_log.csv** in current directory.
117+
118+
{{% notice Note %}}
119+
Script execution can be blocked due to policy configuration. The `Set-ExecutionPolicy` line allows local script to run during this session.
120+
{{% /notice %}}
121+
122+
### Script explained
123+
The `param` section defines variables including binary path, video playback arguments, sampling interval and result file path.
124+
125+
Line 15 - Line 26 check and modify binary file attribute. The binaries in use are downloaded from the web. They can be blocked to run due to lack of signature. These lines unlock the binaries.
126+
127+
Line 41 gets all the child processes of the main process. The statistic data include resources used by all the processes spawned by the main process.
128+
129+
The `while` setction collects processes' CPU and memory usage periodically until the application exits. The CPU usage is accumulated time length that the process runs on CPU. And the memory usage is size of memory occupation with or without shared spaces accounted.
130+
131+
### View result
132+
Shown below is example sample result from running x86_64 version ffplay.exe:
133+
```output
134+
Timestamp,CPU Sum (s),Memory Sum (MB),Memory Private Sum (MB),CPU0 (s),Memory0 (MB),Memory Private0 (MB),CPU1 (s),Memory1 (MB),Memory Private1 (MB)
135+
2025-08-18T10:40:12.3480939+08:00,3.6875,378.65,342.16,3.671875,366.3515625,340.33984375,0.015625,12.296875,1.82421875
136+
......
137+
2025-08-18T10:43:09.7262439+08:00,396.375,391.71,355.00,396.359375,379.453125,353.2421875,0.015625,12.2578125,1.7578125
138+
```
139+
140+
Example result from running Arm64 native ffplay.exe:
141+
```output
142+
Timestamp,CPU Sum (s),Memory Sum (MB),Memory Private Sum (MB),CPU0 (s),Memory0 (MB),Memory Private0 (MB),CPU1 (s),Memory1 (MB),Memory Private1 (MB)
143+
2025-08-18T10:36:04.3654823+08:00,3.296875,340.51,328.17,3.28125,328.18359375,326.359375,0.015625,12.32421875,1.8125
144+
......
145+
2025-08-18T10:39:01.7856168+08:00,329.109375,352.53,339.96,329.09375,340.23046875,338.20703125,0.015625,12.30078125,1.75390625
146+
```
147+
148+
The sample result file is in **csv** format. You can open it with spreadsheet applications like Microsoft Excel for a better view and plot lines for data analysis.

0 commit comments

Comments
 (0)