如何读取系统使用情况(CPU、RAM 等)
How to read system usage (CPU, RAM etc)
在 unity3d 中,我试图读取系统使用情况,以便在一个人玩 VR 游戏时查看 CPU 和 RAM 使用情况。我知道如何在电脑屏幕上显示它,以及如何让它远离玩家的 VR 屏幕。
据我所知,我一直在四处寻找 Google。他们中的大多数都得出相同的答案,但我似乎无法正常工作。
我一直在查看 post:https://answers.unity.com/questions/506736/measure-cpu-and-memory-load-in-code.html which leads me to the Whosebug page: How to get the CPU Usage in C#?
在这些 post 中,他们总是遇到 CPU 使用卡在 100% 的问题,即使这是不正确的。我一直在尝试 System.Threading.Thread.Sleep(1000)。但这会将整个游戏锁定为 1fps,因为它每秒等待 1 秒。即使有 1fps,除了 100%,我无法获得任何其他读取。
在这段代码中,我使用了睡眠线程,它将游戏速度减慢到 1fps
using UnityEngine;
using System.Diagnostics;
using TMPro;
public class DebugUIManager : MonoBehaviour
{
private PerformanceCounter cpuCounter;
[SerializeField] private TMP_Text cpuCounterText;
private void Start()
{
cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
}
private void Update()
{
cpuCounterText.text = getCurrentCpuUsage();
}
private string getCurrentCpuUsage()
{
dynamic firstValue = cpuCounter.NextValue() + "% CPU";
System.Threading.Thread.Sleep(1000);
dynamic secondValue = cpuCounter.NextValue() + "% CPU";
return secondValue;
}
}
每当我更改
private string getCurrentCpuUsage()
{
dynamic firstValue = cpuCounter.NextValue() + "% CPU";
System.Threading.Thread.Sleep(1000);
dynamic secondValue = cpuCounter.NextValue() + "% CPU";
return secondValue;
}
到
private string getCurrentCpuUsage()
{
return cpuCounter.NextValue() + "%";
}
游戏的 fps 不会下降,但它也不会做任何事情。
我没有收到任何错误消息,因为它运行没有问题。但我真的很想知道如何获得 CPU 用法,所以我可以自己弄清楚其余部分。
如有任何帮助,我们将不胜感激。
我试过了,但也无法正确地将 PerformanceCounter
转换为 运行(总是像您一样返回 100%
)
但是我找到了一个很好的替代品 here 并将其用于 re-build 你的 DebugUIManager
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using TMPro;
using UnityEngine;
public class DebugUIManager : MonoBehaviour
{
[Header("Components")]
[SerializeField] private TMP_Text cpuCounterText;
[Header("Settings")]
[Tooltip("In which interval should the CPU usage be updated?")]
[SerializeField] private float updateInterval = 1;
[Tooltip("The amount of physical CPU cores")]
[SerializeField] private int processorCount;
[Header("Output")]
public float CpuUsage;
private Thread _cpuThread;
private float _lasCpuUsage;
private void Start()
{
Application.runInBackground = true;
cpuCounterText.text = "0% CPU";
// setup the thread
_cpuThread = new Thread(UpdateCPUUsage)
{
IsBackground = true,
// we don't want that our measurement thread
// steals performance
Priority = System.Threading.ThreadPriority.BelowNormal
};
// start the cpu usage thread
_cpuThread.Start();
}
private void OnValidate()
{
// We want only the physical cores but usually
// this returns the twice as many virtual core count
//
// if this returns a wrong value for you comment this method out
// and set the value manually
processorCount = SystemInfo.processorCount / 2;
}
private void OnDestroy()
{
// Just to be sure kill the thread if this object is destroyed
_cpuThread?.Abort();
}
private void Update()
{
// for more efficiency skip if nothing has changed
if (Mathf.Approximately(_lasCpuUsage, CpuUsage)) return;
// the first two values will always be "wrong"
// until _lastCpuTime is initialized correctly
// so simply ignore values that are out of the possible range
if (CpuUsage < 0 || CpuUsage > 100) return;
// I used a float instead of int for the % so use the ToString you like for displaying it
cpuCounterText.text = CpuUsage.ToString("F1") + "% CPU";
// Update the value of _lasCpuUsage
_lasCpuUsage = CpuUsage;
}
/// <summary>
/// Runs in Thread
/// </summary>
private void UpdateCPUUsage()
{
var lastCpuTime = new TimeSpan(0);
// This is ok since this is executed in a background thread
while (true)
{
var cpuTime = new TimeSpan(0);
// Get a list of all running processes in this PC
var AllProcesses = Process.GetProcesses();
// Sum up the total processor time of all running processes
cpuTime = AllProcesses.Aggregate(cpuTime, (current, process) => current + process.TotalProcessorTime);
// get the difference between the total sum of processor times
// and the last time we called this
var newCPUTime = cpuTime - lastCpuTime;
// update the value of _lastCpuTime
lastCpuTime = cpuTime;
// The value we look for is the difference, so the processor time all processes together used
// since the last time we called this divided by the time we waited
// Then since the performance was optionally spread equally over all physical CPUs
// we also divide by the physical CPU count
CpuUsage = 100f * (float)newCPUTime.TotalSeconds / updateInterval / processorCount;
// Wait for UpdateInterval
Thread.Sleep(Mathf.RoundToInt(updateInterval * 1000));
}
}
}
在 unity3d 中,我试图读取系统使用情况,以便在一个人玩 VR 游戏时查看 CPU 和 RAM 使用情况。我知道如何在电脑屏幕上显示它,以及如何让它远离玩家的 VR 屏幕。
据我所知,我一直在四处寻找 Google。他们中的大多数都得出相同的答案,但我似乎无法正常工作。
我一直在查看 post:https://answers.unity.com/questions/506736/measure-cpu-and-memory-load-in-code.html which leads me to the Whosebug page: How to get the CPU Usage in C#?
在这些 post 中,他们总是遇到 CPU 使用卡在 100% 的问题,即使这是不正确的。我一直在尝试 System.Threading.Thread.Sleep(1000)。但这会将整个游戏锁定为 1fps,因为它每秒等待 1 秒。即使有 1fps,除了 100%,我无法获得任何其他读取。
在这段代码中,我使用了睡眠线程,它将游戏速度减慢到 1fps
using UnityEngine;
using System.Diagnostics;
using TMPro;
public class DebugUIManager : MonoBehaviour
{
private PerformanceCounter cpuCounter;
[SerializeField] private TMP_Text cpuCounterText;
private void Start()
{
cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
}
private void Update()
{
cpuCounterText.text = getCurrentCpuUsage();
}
private string getCurrentCpuUsage()
{
dynamic firstValue = cpuCounter.NextValue() + "% CPU";
System.Threading.Thread.Sleep(1000);
dynamic secondValue = cpuCounter.NextValue() + "% CPU";
return secondValue;
}
}
每当我更改
private string getCurrentCpuUsage()
{
dynamic firstValue = cpuCounter.NextValue() + "% CPU";
System.Threading.Thread.Sleep(1000);
dynamic secondValue = cpuCounter.NextValue() + "% CPU";
return secondValue;
}
到
private string getCurrentCpuUsage()
{
return cpuCounter.NextValue() + "%";
}
游戏的 fps 不会下降,但它也不会做任何事情。
我没有收到任何错误消息,因为它运行没有问题。但我真的很想知道如何获得 CPU 用法,所以我可以自己弄清楚其余部分。
如有任何帮助,我们将不胜感激。
我试过了,但也无法正确地将 PerformanceCounter
转换为 运行(总是像您一样返回 100%
)
但是我找到了一个很好的替代品 here 并将其用于 re-build 你的 DebugUIManager
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using TMPro;
using UnityEngine;
public class DebugUIManager : MonoBehaviour
{
[Header("Components")]
[SerializeField] private TMP_Text cpuCounterText;
[Header("Settings")]
[Tooltip("In which interval should the CPU usage be updated?")]
[SerializeField] private float updateInterval = 1;
[Tooltip("The amount of physical CPU cores")]
[SerializeField] private int processorCount;
[Header("Output")]
public float CpuUsage;
private Thread _cpuThread;
private float _lasCpuUsage;
private void Start()
{
Application.runInBackground = true;
cpuCounterText.text = "0% CPU";
// setup the thread
_cpuThread = new Thread(UpdateCPUUsage)
{
IsBackground = true,
// we don't want that our measurement thread
// steals performance
Priority = System.Threading.ThreadPriority.BelowNormal
};
// start the cpu usage thread
_cpuThread.Start();
}
private void OnValidate()
{
// We want only the physical cores but usually
// this returns the twice as many virtual core count
//
// if this returns a wrong value for you comment this method out
// and set the value manually
processorCount = SystemInfo.processorCount / 2;
}
private void OnDestroy()
{
// Just to be sure kill the thread if this object is destroyed
_cpuThread?.Abort();
}
private void Update()
{
// for more efficiency skip if nothing has changed
if (Mathf.Approximately(_lasCpuUsage, CpuUsage)) return;
// the first two values will always be "wrong"
// until _lastCpuTime is initialized correctly
// so simply ignore values that are out of the possible range
if (CpuUsage < 0 || CpuUsage > 100) return;
// I used a float instead of int for the % so use the ToString you like for displaying it
cpuCounterText.text = CpuUsage.ToString("F1") + "% CPU";
// Update the value of _lasCpuUsage
_lasCpuUsage = CpuUsage;
}
/// <summary>
/// Runs in Thread
/// </summary>
private void UpdateCPUUsage()
{
var lastCpuTime = new TimeSpan(0);
// This is ok since this is executed in a background thread
while (true)
{
var cpuTime = new TimeSpan(0);
// Get a list of all running processes in this PC
var AllProcesses = Process.GetProcesses();
// Sum up the total processor time of all running processes
cpuTime = AllProcesses.Aggregate(cpuTime, (current, process) => current + process.TotalProcessorTime);
// get the difference between the total sum of processor times
// and the last time we called this
var newCPUTime = cpuTime - lastCpuTime;
// update the value of _lastCpuTime
lastCpuTime = cpuTime;
// The value we look for is the difference, so the processor time all processes together used
// since the last time we called this divided by the time we waited
// Then since the performance was optionally spread equally over all physical CPUs
// we also divide by the physical CPU count
CpuUsage = 100f * (float)newCPUTime.TotalSeconds / updateInterval / processorCount;
// Wait for UpdateInterval
Thread.Sleep(Mathf.RoundToInt(updateInterval * 1000));
}
}
}