Last active
August 10, 2025 08:31
-
-
Save pedoc/6df293146b8d1d2a6077568a05b196dd to your computer and use it in GitHub Desktop.
performance monitor in windows
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
param( | |
[string]$ReportFile = "$(Join-Path $PSScriptRoot 'report.txt')" | |
) | |
Clear-Host | |
$ErrorActionPreference = "Stop" | |
try { | |
Start-Transcript -Path $ReportFile | |
# 检测 NVIDIA SMI 是否可用 | |
function Get-GpuMetrics { | |
if (Get-Command nvidia-smi -ErrorAction SilentlyContinue) { | |
$gpuData = & nvidia-smi --query-gpu=name,utilization.gpu,utilization.decoder,memory.total,memory.used --format=csv,noheader,nounits | |
$gpuList = @() | |
foreach ($line in $gpuData) { | |
$parts = $line -split "," | |
$gpuList += @{ | |
Name = $parts[0].Trim() | |
GPUUtil = [double]$parts[1] | |
DecoderUtil = [double]$parts[2] | |
MemTotal = [double]$parts[3] | |
MemUsed = [double]$parts[4] | |
} | |
} | |
return $gpuList | |
} else { | |
return @() | |
} | |
} | |
# ========== 系统信息 ========== | |
$os = Get-CimInstance Win32_OperatingSystem | |
$cpu = Get-CimInstance Win32_Processor | |
$board = Get-CimInstance Win32_BaseBoard | |
$gpus = Get-CimInstance Win32_VideoController | |
$memTotalGB = [math]::Round($os.TotalVisibleMemorySize / 1MB, 2) | |
Write-Host "=== 系统信息 ===" | |
Write-Host "操作系统: $($os.Caption) $($os.OSArchitecture)" | |
Write-Host "版本: $($os.Version)" | |
Write-Host "主板: $($board.Manufacturer) $($board.Product)" | |
Write-Host "CPU: $($cpu.Name) ($($cpu.NumberOfCores) 核心 / $($cpu.NumberOfLogicalProcessors) 线程 @ $($cpu.MaxClockSpeed) MHz)" | |
Write-Host "总内存: $memTotalGB GB" | |
# 内存硬件信息 | |
$memModules = Get-CimInstance Win32_PhysicalMemory | |
Write-Host "内存条信息:" | |
foreach ($m in $memModules) { | |
$capGB = "{0:N2}" -f ($m.Capacity / 1GB) | |
Write-Host (" - 槽位 {0} ({1}) | {2} {3} | {4} GB @ {5} MHz" -f ` | |
$m.BankLabel, $m.DeviceLocator, $m.Manufacturer, $m.PartNumber.Trim(), | |
$capGB, $m.Speed) | |
} | |
Write-Host "GPU(s):" | |
Write-Host " - name driver.version memory.used memory.free memory.total" | |
foreach ($gpu in $gpus) { | |
# Write-Host " - $($gpu.Name) (${($gpu.AdapterRAM/1GB):N2} GB)" | |
Write-Host " - $(nvidia-smi --query-gpu=name,driver_version,memory.used,memory.free,memory.total --format=csv,noheader)" | |
} | |
# 网卡信息 | |
$excludePatterns = @('VMware', 'Virtual', 'Hyper-V', 'VirtualBox', 'Loopback') | |
Write-Host "Network(s):" | |
$netAdapters = Get-NetAdapter | Where-Object { $_.Status -eq "Up" } | Sort-Object -Property Name | |
foreach ($adapter in $netAdapters) { | |
$wmi = Get-CimInstance Win32_NetworkAdapter | Where-Object { $_.NetConnectionID -eq $adapter.Name } | |
$pnpId = $wmi.PNPDeviceID | |
$desc = $wmi.Description | |
$isVirtual = $false | |
foreach ($pattern in $excludePatterns) { | |
if (($pnpId -and $pnpId -like "*$pattern*") -or ($desc -and $desc -like "*$pattern*")) { | |
$isVirtual = $true | |
break | |
} | |
} | |
if ($isVirtual) { continue } # 跳过虚拟网卡 | |
$model = if ($wmi) { $wmi.Name } else { "未知型号" } | |
Write-Host (" - {0} | MAC: {1} | 速度: {2} Gbps | 状态: {3} | 型号: {4}" -f ` | |
$adapter.Name, $adapter.MacAddress, $adapter.LinkSpeed, $adapter.Status, $model) | |
} | |
Write-Host "" | |
# 初始快照 | |
$cpuSnap = (Get-Counter "\Processor(_Total)\% Processor Time").CounterSamples.CookedValue | |
$memFreeGB = [math]::Round($os.FreePhysicalMemory / 1MB, 2) | |
$memUsedSnapGB = $memTotalGB - $memFreeGB | |
$gpuSnap = Get-GpuMetrics | |
Write-Host "=== 初始快照 ===" | |
Write-Host ("CPU 使用率: {0:N2}%" -f $cpuSnap) | |
Write-Host ("内存占用: {0:N2} GB" -f $memUsedSnapGB) | |
Write-Host ("GPU 占用: {0:N2}%" -f ($gpuSnap | Measure-Object -Property GPUUtil -Average).Average) | |
Write-Host ("视频引擎占用: {0:N2}%" -f ($gpuSnap | Measure-Object -Property DecoderUtil -Average).Average) | |
Write-Host ("显存占用: {0:N2} MB" -f ($gpuSnap | Measure-Object -Property MemUsed -Sum).Sum) | |
Write-Host "" | |
Write-Host "开始性能监控... 按 q + 回车 停止。" | |
Write-Host "" | |
# 统计数据 | |
$cpuList = @() | |
$memList = @() | |
$diskReadList = @() | |
$diskWriteList = @() | |
$netRecvList = @() | |
$netSendList = @() | |
$gpuUtilList = @() | |
$gpuMemList = @() | |
$decoderUtilList = @() | |
$startTime = Get-Date | |
# 监控循环 | |
while ($true) { | |
if ([console]::KeyAvailable) { | |
$key = [console]::ReadKey($true).KeyChar | |
if ($key -eq 'q') { break } | |
} | |
# 需要监控的计数器列表 | |
$counters = @( | |
'\Processor(_Total)\% Processor Time', | |
'\PhysicalDisk(_Total)\Disk Read Bytes/sec', | |
'\PhysicalDisk(_Total)\Disk Write Bytes/sec', | |
'\Network Interface(*)\Bytes Received/sec', | |
'\Network Interface(*)\Bytes Sent/sec' | |
) | |
# 一次采样,采样间隔1秒,采样1次 | |
$results = Get-Counter -Counter $counters -SampleInterval 1 -MaxSamples 1 | |
# CPU 使用率 | |
$cpuUsage = ($results.CounterSamples | Where-Object { $_.Path -like '*Processor(_Total)*' }).CookedValue | |
# 磁盘读取 (MB/s) | |
$diskRead = ($results.CounterSamples | Where-Object { $_.Path -like '*PhysicalDisk(_Total)\\Disk Read Bytes/sec*' }).CookedValue / 1MB | |
# 磁盘写入 (MB/s) | |
$diskWrite = ($results.CounterSamples | Where-Object { $_.Path -like '*PhysicalDisk(_Total)\\Disk Write Bytes/sec*' }).CookedValue / 1MB | |
# 网络接收 (KB/s) 多网卡求和 | |
$netRecv = ($results.CounterSamples | Where-Object { $_.Path -like '*Network Interface(*)\\Bytes Received/sec*' } | Measure-Object -Property CookedValue -Sum).Sum / 1KB | |
# 网络发送 (KB/s) 多网卡求和 | |
$netSend = ($results.CounterSamples | Where-Object { $_.Path -like '*Network Interface(*)\\Bytes Sent/sec*' } | Measure-Object -Property CookedValue -Sum).Sum / 1KB | |
# 内存信息(调用不变) | |
$memFreeGB = [math]::Round((Get-CimInstance Win32_OperatingSystem).FreePhysicalMemory / 1MB, 2) | |
$memUsedGB = $memTotalGB - $memFreeGB | |
# GPU 信息(保持不变) | |
$gpuData = Get-GpuMetrics | |
$gpuUtil = if ($gpuData.Count -gt 0) { ($gpuData | Measure-Object -Property GPUUtil -Average).Average } else { 0 } | |
$decoderUtil = if ($gpuData.Count -gt 0) { ($gpuData | Measure-Object -Property DecoderUtil -Average).Average } else { 0 } | |
$gpuMemUsed = if ($gpuData.Count -gt 0) { ($gpuData | Measure-Object -Property MemUsed -Sum).Sum } else { 0 } | |
# 存储数据 | |
$cpuList += $cpuUsage | |
$memList += $memUsedGB | |
$diskReadList += $diskRead | |
$diskWriteList += $diskWrite | |
$netRecvList += $netRecv | |
$netSendList += $netSend | |
$gpuUtilList += $gpuUtil | |
$gpuMemList += $gpuMemUsed | |
$decoderUtilList += $decoderUtil | |
# 实时输出 | |
Write-Host ("[{0:HH:mm:ss}] | CPU: {1,6:N2}% | 内存: {2,6:N2} GB | 磁盘R/W: {3,6:N2}/{4,6:N2} MB/s | 网络R/W: {5,6:N2}/{6,6:N2} KB/s | GPU: {7,6:N2}% | 视频引擎: {8,6:N2}% | 显存: {9,6:N2} MB" -f ` | |
(Get-Date), $cpuUsage, $memUsedGB, $diskRead, $diskWrite, $netRecv, $netSend, $gpuUtil, $decoderUtil, $gpuMemUsed) | |
# Start-Sleep -Seconds 1 | |
} | |
# 退出统计 | |
$endTime = Get-Date | |
$duration = $endTime - $startTime | |
# 监控结果 | |
Write-Host "=== 监控统计结果 ===" | |
Write-Host "运行时长: $duration" | |
function Output-Stat($name, $unit, $list) { | |
if ($list.Count -gt 0) { | |
Write-Host ("{0} 平均: {1:N2} {4} | 最大: {2:N2} {4} | 最小: {3:N2} {4}" -f ` | |
$name, ` | |
($list | Measure-Object -Average).Average, ` | |
($list | Measure-Object -Maximum).Maximum, ` | |
($list | Measure-Object -Minimum).Minimum, ` | |
$unit) | |
} | |
} | |
Output-Stat "CPU 使用率" "%" $cpuList | |
Output-Stat "内存占用" "GB" $memList | |
Output-Stat "磁盘读取" "MB/s" $diskReadList | |
Output-Stat "磁盘写入" "MB/s" $diskWriteList | |
Output-Stat "网络接收" "KB/s" $netRecvList | |
Output-Stat "网络发送" "KB/s" $netSendList | |
Output-Stat "GPU 利用率" "%" $gpuUtilList | |
Output-Stat "视频引擎利用率" "%" $decoderUtilList | |
Output-Stat "GPU 显存占用" "MB" $gpuMemList | |
} | |
finally{ | |
Stop-Transcript | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment