簡體   English   中英

計算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-和CPU的使用率分析/

代碼段:

    /// <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%%\r\n", percentIdle);
    }

    return 0;
}

在大多數CE平台上,每秒執行一次此計算的開銷絕對可以忽略不計。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM