在MATLAB中展示CPU核心利用率

8
有没有什么方法(任何函数等)可以在MATLAB中显示CPU核心利用率,就像Windows任务管理器的性能选项卡中那样,在GUI中显示?
谢谢。

你需要针对Windows、Unix等特定平台的解决方案,还是跨平台的解决方案? - Hoki
我正在Windows平台上运行我的GUI。如果可以的话,请描述一下在Windows和跨平台上的解决方案。谢谢。 - Eghbal
抱歉,现在我正在使用Windows 8,似乎无法恢复我的旧跨平台解决方案。它涉及一些Java类。仍然有一个仅适用于Windows的工作解决方案,但它严重依赖于从Matlab调用的.net类(除了显示部分外,几乎没有本地Matlab)。稍后我会尝试起草一个示例。 - Hoki
2个回答

9
据我所知,没有Matlab函数可以在进程使用级别访问系统属性。要获取此信息,必须调用外部类。
在互联网上搜索可以为您检索一些可查询进程属性的Java类。Java方法的优点在于更可能跨平台。
对于Windows用户,仍有两种查询这些信息的方法:通过直接调用Windows API(速度较快,但在Matlab中放置相当复杂),以及使用.net对象(速度较慢,但由于Matlab几乎无缝地处理.net类,因此非常容易)。
  • 创建对象

我们需要告诉Matlab实例化一个System.Diagnostics.PerformanceCounter对象。例如,我创建了两个这样的对象,一个用于查看系统空闲进程(称为Idle),另一个用于查看Matlab进程(这个将报告Matlab的CPU使用情况)。

function mon = createMonitor
   MatlabProcess = System.Diagnostics.Process.GetCurrentProcess(); % "Matlab" process
   cpuIdleProcess = 'Idle' ;
   mon.NumOfCPU = double(System.Environment.ProcessorCount);
   mon.ProcPerfCounter.Matlab  = System.Diagnostics.PerformanceCounter('Process', '% Processor Time', MatlabProcess.ProcessName );
   mon.ProcPerfCounter.cpuIdle = System.Diagnostics.PerformanceCounter('Process', '% Processor Time', cpuIdleProcess );
end

  • 查询对象

使用Windows API,我们需要自己进行大量的机器周期计算,但这些.NET对象很整洁,因为它们为您完成了所有这些工作(尽管以性能为代价)。所以现在只需要调用对象并询问最后一次CPU使用情况... 很容易。

唯一要注意的细节是,报告的数字仅适用于进程使用的处理器核心,因此如果您有多个核心,则报告的数字必须除以处理器总数才能得到一个整体数字。

   % Calculate the cpu usage
   cpu.total = 100 - h.mon.ProcPerfCounter.cpuIdle.NextValue / h.mon.NumOfCPU ;
   cpu.matlab = h.mon.ProcPerfCounter.Matlab.NextValue / h.mon.NumOfCPU ;

  • 显示

搞定了。最困难的部分是知道和访问这些 .net 的微妙之处。现在,如果你想要一个真正的监视器,你需要定义一个定时器,定时调用这些方法,然后显示结果。

只要注意调用这些 .net 对象在处理器时间上相当昂贵,因此,如果你创建太多的 PerformanceCounter,你的监视器将占用大部分处理器时间(例如每个进程一个计数器会很费力)...而且不要试图以疯狂的短间隔刷新你的定时器。


  • 完全功能的示例:

抱歉,但其中90%仅用于GUI机制(我尽可能粗略地保留),因此我不会解释所有内容。唯一重要的部分是上面显示的代码片段(包含在下面的完全功能示例中)。

function hcol = CPU_monitor

h = create_gui ;

end

function mon = createMonitor
   MatlabProcess = System.Diagnostics.Process.GetCurrentProcess(); %// "Matlab" process
   cpuIdleProcess = 'Idle' ;
   mon.NumOfCPU = double(System.Environment.ProcessorCount);
   mon.ProcPerfCounter.Matlab  = System.Diagnostics.PerformanceCounter('Process', '% Processor Time', MatlabProcess.ProcessName );
   mon.ProcPerfCounter.cpuIdle = System.Diagnostics.PerformanceCounter('Process', '% Processor Time', cpuIdleProcess );
end

function updateMeasure(obj,evt,hfig)
   h = guidata(hfig) ;
   %// Calculate the cpu usage
   cpu.total = 100 - h.mon.ProcPerfCounter.cpuIdle.NextValue / h.mon.NumOfCPU ;
   cpu.matlab = h.mon.ProcPerfCounter.Matlab.NextValue / h.mon.NumOfCPU ;
   %// update the display
   set(h.txtTotalCPU,'String',num2str(cpu.total,'%5.2f %%') )
   set(h.txtMatlabCPU,'String',num2str(cpu.matlab,'%5.2f %%') )
end

function StartMonitor(obj,evt)
   h = guidata(obj) ;
   start(h.t)
end
function StopMonitor(obj,evt)
   h = guidata(obj) ;
   stop(h.t)
end

function h = create_gui %// The boring part

   h.fig = figure('Unit','Pixels','Position',[200 800 240 120],'MenuBar','none','Name','CPU usage %','NumberTitle','off') ;

   h.btnStart = uicontrol('Callback',@StartMonitor,'Position',[10 80 100 30],'String', 'START' );
   h.btnStart = uicontrol('Callback',@StopMonitor,'Position',[130 80 100 30 ],'String', 'STOP' );

   h.lbl1 = uicontrol('HorizontalAlignment','right','Position',[10 50 100 20],'String','TOTAL :','Style','text' );
   h.txtTotalCPU = uicontrol('Position',[130 50 100 20],'String','0','Style','text' ) ;

   h.lbl2 = uicontrol('HorizontalAlignment','right','Position',[10 10 100 20],'String','Matlab :','Style','text' );
   h.txtMatlabCPU = uicontrol('Position',[130 10 100 20],'String','0','Style','text' ) ;

   movegui(h.fig,'center')

   %// create the monitor
   h.mon = createMonitor ;

   %// Create the timer
   h.t = timer;
   h.t.Period = 1;
   h.t.ExecutionMode = 'fixedRate';
   h.t.TimerFcn = {@updateMeasure,h.fig} ;
   h.t.TasksToExecute = Inf;

   %// store the handle collection
   guidata(h.fig,h)

end

0
如果您在Linux上使用Matlab,可以设置cronjob将/proc/loadavg的内容写入到Matlab路径上的文件中。该文件的内容提供了1分钟、5分钟和15分钟的CPU负载平均值。然后,您可以让Matlab定期读取此文件。这种解决方案的时间分辨率并不是很高,但如果您可以处理大约1分钟的更新,则应该足够了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接