计算Windows Mobile/CE设备的当前CPU占用率
Calculating the current CPU usage on a Windows Mobile/CE device
在核心系统中,没有单个调用检索整个系统的CPU使用情况。从我能在网上找到的零碎的样本代码,我需要计算这个总数%,但我不能得到我的头周围的数学涉及,我希望有人能在这方面提供帮助。
我用c#写这个,并调用一些函数来获得线程计时。下面是我目前得到的代码。对于每个正在运行的线程,我可以使用GetThreadTick和GetThreadTimings获得计时。我无法想象这些值将如何帮助我计算CPU使用率%。
我也意识到我所做的任何计算都会影响CPU使用率本身。
public static int Calc()
{
int dwCurrentThreadTime1 = 0;
int dwCurrentThreadTime2 = 0;
FILETIME ftCreationTime = new FILETIME();
FILETIME ftExitTime = new FILETIME();
FILETIME ftKernelTime = new FILETIME();
FILETIME ftUserTime = new FILETIME();
PROCESSENTRY pe32 = new PROCESSENTRY();
THREADENTRY32 te32 = new THREADENTRY32();
IntPtr hsnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST | TH32CS_SNAPMODULE | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, 0);
if (hsnapshot == IntPtr.Zero)
return -1;
pe32.dwSize = (uint)Marshal.SizeOf(pe32);
te32.dwSize = Marshal.SizeOf(te32);
int retval = Process32First(hsnapshot, ref pe32);
while (retval == 1)
{
int retval2 = Thread32First(hsnapshot, ref te32);
while(retval2 == 1)
{
if (te32.th32OwnerProcessID == pe32.th32ProcessID)
{
int dwCurrentTickTime1 = GetTickCount();
GetThreadTimes((IntPtr)te32.th32ThreadID, ref ftCreationTime, ref ftExitTime, ref ftKernelTime, ref ftUserTime);
GetThreadTick(ref ftKernelTime, ref ftUserTime);
}
retval2 = Thread32Next(hsnapshot, ref te32);
}
retval = Process32Next(hsnapshot, ref pe32);
}
CloseToolhelp32Snapshot(hsnapshot);
return dwCurrentThreadTime1;
}
您可以使用GetIdleTime或CeGetIdleTimeEx(单核或多核版本)获取CPU在空闲状态下花费的时间,并使用该值计算CPU(或每个核)的负载百分比。此函数要求BSP支持空闲计数器,如果BSP中缺少此支持,您将无法获得有意义的值。
在我的cpumon中,我使用GetThreadTick来表示所有线程的用户和内核时间,并为所有进程构建一个总和:http://www.hjgode.de/wp/2012/12/14/mobile-development-a-remote-cpu-monitor-and-cpu-usage-analysis/
代码片段:
/// <summary>
/// build thread and process list periodically and fire update event and enqueue results for the socket thread
/// </summary>
void usageThread()
{
try
{
int interval = 3000;
uint start = Process.GetTickCount();
Dictionary<uint, thread> old_thread_List;// = Process.GetThreadList();
string exeFile = Process.exefile;
//read all processes
Dictionary<uint, process> ProcList = Process.getProcessNameList();
DateTime dtCurrent = DateTime.Now;
//######### var declarations
Dictionary<uint, thread> new_ThreadList;
uint duration;
long system_total;
long user_total, kernel_total; //total process spend in user/kernel
long thread_user, thread_kernel; //times the thread spend in user/kernel
DWORD dwProc;
float user_percent;
float kernel_percent;
ProcessStatistics.process_usage usage;
ProcessStatistics.process_statistics stats = null;
string sProcessName = "";
List<thread> processThreadList = new List<thread>();
//extended list
List<threadStatistic> processThreadStatsList = new List<threadStatistic>(); //to store thread stats
while (!bStopMainThread)
{
eventEnableCapture.WaitOne();
old_thread_List = Process.GetThreadList(); //build a list of threads with user and kernel times
System.Threading.Thread.Sleep(interval);
//get a new thread list
new_ThreadList = Process.GetThreadList(); //build another list of threads with user and kernel times, to compare
duration = Process.GetTickCount() - start;
ProcList = Process.getProcessNameList(); //update process list
dtCurrent = DateTime.Now;
system_total = 0;
statisticsTimes.Clear();
//look thru all processes
foreach (KeyValuePair<uint, process> p2 in ProcList)
{
//empty the process's thread list
processThreadList=new List<thread>();
processThreadStatsList = new List<threadStatistic>();
user_total = 0; //hold sum of thread user times for a process
kernel_total = 0; //hold sum of thread kernel times for a process
sProcessName = p2.Value.sName;
//SUM over all threads with that ProcID
dwProc = p2.Value.dwProcID;
foreach (KeyValuePair<uint, thread> kpNew in new_ThreadList)
{
thread_user = 0;
thread_kernel = 0;
//if the thread belongs to the process
if (kpNew.Value.dwOwnerProcID == dwProc)
{
//is there an old thread entry we can use to calc?
thread threadOld;
if (old_thread_List.TryGetValue(kpNew.Value.dwThreadID, out threadOld))
{
thread_user=Process.GetThreadTick(kpNew.Value.thread_times.user) - Process.GetThreadTick(old_thread_List[kpNew.Value.dwThreadID].thread_times.user);
user_total += thread_user;
thread_kernel =Process.GetThreadTick(kpNew.Value.thread_times.kernel) - Process.GetThreadTick(old_thread_List[kpNew.Value.dwThreadID].thread_times.kernel);
kernel_total += thread_kernel;
}
//simple list
thread threadsOfProcess = new thread(kpNew.Value.dwOwnerProcID, kpNew.Value.dwThreadID, kpNew.Value.thread_times);
processThreadList.Add(threadsOfProcess);
//extended list
threadStatistic threadStats =
new threadStatistic(
kpNew.Value.dwOwnerProcID,
kpNew.Value.dwThreadID,
new threadtimes(thread_user, thread_kernel),
duration,
dtCurrent.Ticks);
processThreadStatsList.Add(threadStats);
}//if dwProcID matches
}
//end of sum for process
user_percent = (float)user_total / (float)duration * 100f;
kernel_percent = (float)kernel_total / (float)duration * 100f;
system_total = user_total + kernel_total;
// update the statistics with this process' info
usage = new ProcessStatistics.process_usage(kernel_total, user_total);
// update process statistics
stats = new ProcessStatistics.process_statistics(p2.Value.dwProcID, p2.Value.sName, usage, dtCurrent.Ticks, duration, processThreadStatsList);
//add or update the proc stats
if (exeFile != p2.Value.sName || bIncludeMySelf)
{
statisticsTimes[p2.Value.sName] = stats;
procStatsQueueBytes.Enqueue(stats.ToByte());
}
start = Process.GetTickCount();
}//foreach process
onUpdateHandler(new ProcessStatsEventArgs(statisticsTimes, duration));
procStatsQueueBytes.Enqueue(ByteHelper.endOfTransferBytes);
((AutoResetEvent)eventEnableSend).Set();
}//while true
}
catch (ThreadAbortException ex)
{
System.Diagnostics.Debug.WriteLine("ThreadAbortException: usageThread(): " + ex.Message);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("Exception: usageThread(): " + ex.Message);
}
System.Diagnostics.Debug.WriteLine("Thread ENDED");
}
获得整个系统空闲时间的计算在MSDN上有文档记录。
下面是一个c#示例:
using System;
using System.Runtime.InteropServices;
using System.Threading;
class Program
{
static void Main()
{
for(;;)
{
uint startTick = GetTickCount();
uint startIdle = GetIdleTime();
Thread.Sleep(1000);
uint stopTick = GetTickCount();
uint stopIdle = GetIdleTime();
uint percentIdle = (100 * (stopIdle - startIdle)) / stopTick - startTick);
Console.WriteLine("CPU idle {0}%", percentIdle);
}
}
[DllImport("coredll.dll")]
static extern uint GetTickCount();
[DllImport("coredll.dll")]
static extern uint GetIdleTime();
}
和等价的C/c++实现:
#include "windows.h"
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
for(;;)
{
DWORD startTick = GetTickCount();
DWORD startIdle = GetIdleTime();
Sleep(1000);
DWORD stopTick = GetTickCount();
DWORD stopIdle = GetIdleTime();
DWORD percentIdle = (100 * (stopIdle - startIdle)) / (stopTick - startTick);
_tprintf(L"CPU idle %d%%rn", percentIdle);
}
return 0;
}
在大多数CE平台上,每秒执行一次此计算的开销完全可以忽略不计。
相关文章:
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 在模拟器中使用并集来模拟CPU寄存器有多合适
- 编写一个函数以使用 n 百分比的 CPU 使用率
- 如何禁用 CPU 的无序执行
- CPU 瓶颈;处理具有许多非静态对象的 3D 场景渲染的简单方法
- 分别测量每个线程上花费的 CPU 时间(C++)
- 什么时候最好在子进程中使用 CPU 或 I/O 密集型代码 [ C++ ]
- 在程序运行时监视 VxWorks 中的任务 CPU 利用率
- 对于等待以 std::future wait() 返回的函数的 CPU 使用率或检查标志在循环中休眠一段时间哪个更好?
- 您选择的 CPU 不支持 x86-64 指令集
- 如何降低应用程序的 CPU 使用率?
- 对于 CPU 无法原子操作的类型,std::atomic 有什么意义?
- 如何区分CPU和内存瓶颈?
- 如何以编程方式获取任务管理器进程CPU使用率(不是PerfMon API)
- CPU 如何提供memory_order_acquire保证?
- 一段时间后 CPU 使用率高
- 困于让占用率随着输入而变化,并根据容量进行检查
- 计算Windows Mobile/CE设备的当前CPU占用率
- 获取当前进程CPU占用率
- QWebEnginePage CPU占用率异常