【Unity】CPU使用率を取得してみた
Post : 2023/12/3 Update : 2023/12/16
前回UnityでC#からCPU使用率を取得しようとしたら、うまくいかなった。
今回C++からパフォーマンスカウンターにアクセスして同じことをしてみる。
C++
まずはコンソールに出力してみる
▼▼▼コード全文▼▼▼
#include <Windows.h>
#include <Pdh.h>
#include <iostream>
#pragma comment(lib, "pdh.lib")
int main()
{
PDH_HQUERY cpuQuery;
PDH_HCOUNTER cpuTotal;
//パフォーマンスデータの新規クエリーを作成
PdhOpenQuery(NULL, NULL, &cpuQuery);
//全体のCPU使用率のカウンターをクエリーに追加
PdhAddCounter(
cpuQuery,
L"\\Processor Information(_Total)\\% Processor Utility",
NULL,
&cpuTotal);
// 1秒ごとにCPU使用率を表示
for (int i = 0; i < 10; ++i) {
PDH_FMT_COUNTERVALUE counterVal;
//データの収集
PdhCollectQueryData(cpuQuery);
//CounterValue(表示可能な値)の取得
PdhGetFormattedCounterValue(cpuTotal, PDH_FMT_DOUBLE, NULL, &counterVal);
std::cout << "CPU Usage:" << counterVal.doubleValue << std::endl;
Sleep(1000);
}
//クエリーの終了
PdhCloseQuery(cpuQuery);
return 0;
}
実行するとこんな感じに表示されると思います。
Unity
これをUnity側から使えるように変更します。
C++
C++側ではスレッドを立てて1秒間隔でCPU使用率を取得、変数に格納します。
#include <Windows.h>
#include <Pdh.h>
#include <thread>
#pragma comment(lib, "pdh.lib")
BOOL running = FALSE;
PDH_HQUERY cpuQuery;
PDH_HCOUNTER cpuTotal;
std::thread updateThread;
double cpuUsage;
void update();
extern "C" _declspec(dllexport) void __stdcall Start() {
//パフォーマンスデータの新規クエリーを作成
PdhOpenQuery(NULL, NULL, &cpuQuery);
//全体のCPU使用率のカウンターをクエリーに追加
PdhAddCounter(
cpuQuery,
L"\\Processor Information(_Total)\\% Processor Utility",
NULL,
&cpuTotal);
running = TRUE;
updateThread = std::thread(update);
}
extern "C" _declspec(dllexport) double __stdcall GetCpuUsage() {
return cpuUsage;
}
extern "C" _declspec(dllexport) void __stdcall Stop()
{
running = FALSE;
updateThread.join();
//クエリーの終了
PdhCloseQuery(cpuQuery);
}
void update()
{
//データの収集(初回)
PdhCollectQueryData(cpuQuery);
while (running)
{
// 1秒ごとにCPU使用率を取得
Sleep(1000);
PDH_FMT_COUNTERVALUE counterVal;
//データの収集(前回の値からの差分)
PdhCollectQueryData(cpuQuery);
//CounterValueの取得
PdhGetFormattedCounterValue(cpuTotal, PDH_FMT_DOUBLE, NULL, &counterVal);
cpuUsage = counterVal.doubleValue;
}
}
Unity(C#側)
UnityのUpdate関数内で取得します。(すみません適当で)
using System.Runtime.InteropServices;
using UnityEngine;
public class Scripts : MonoBehaviour
{
static class CpuDll
{
[DllImport("CPU-DLL", CallingConvention = CallingConvention.StdCall)]
public static extern int Start();
[DllImport("CPU-DLL", CallingConvention = CallingConvention.StdCall)]
public static extern int Stop();
[DllImport("CPU-DLL", CallingConvention = CallingConvention.StdCall)]
public static extern double GetCpuUsage();
}
void Start()
{
CpuDll.Start();
}
float elapsedTime = 0;
void Update()
{
if(elapsedTime > 1) {
Debug.Log(CpuDll.GetCpuUsage());
elapsedTime = 0;
}
elapsedTime += Time.deltaTime;
}
private void OnApplicationQuit()
{
CpuDll.Stop();
}
}
以下の感じで取得できていれば成功です!
書いてから気づいたのですが、UnityのUpdateから直接CPUを取得してもいい気がします。
以上、UnityからCPU使用率を取得する方法でした!