Is anyway (any function etc) to show CPU cores utilization
in MATLAB
in a GUI
likes that we have in Task Manager
of windows (Performance Tab)?
Thanks.
To my knowledge, there are no Matlab function which can access the system properties at the level of the process usage. To get this information one must call external classes.
A search on internet can fetch you some Java classes which can query the process properties. The advantage of the Java approach is it is more likely to be cross-platform.
For windows user, there are still 2 ways of querying these information: by direct call to windows API (faster, but quite complicated to put in place in Matlab), and by using .net
object (slower, but uber easy as Matlab handle .net classes almost seamlessly).
We need to tell Matlab to instantiate a System.Diagnostics.PerformanceCounter object. For the example /i create two of these objects, one which looks at the System Idle Process (called Idle
) and one which looks at the Matlab process (this one will report Matlab CPU usage).
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
With windows API we'd have to do a lot of machine cycle calculations ourselves, but these .net object are neat because they do all that for you (at a cost of performance though). So now it is only a matter of calling the object and asking what was the last CPU usage ... easy.
The only detail to care for, is that the number reported is only for the processor core which was in use by the process, so if you have multiple core, the reported number has to be divided by the total number of processor to get an overall figure.
% 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 ;
There you go. The most difficult part was to know and access these .net
subtleties. Now if you want a true monitor, you'll need to define a timer which will call these methods at regular interval, then display the results.
Just be aware that calling these .net
objects is quite expensive in processor time, so if you create too many PerformanceCounter
your monitor will end up eating most of the processor time (one for each process would be quite taxing for example) ... and don't try to refresh your timer at crazy short intervals either
Sorry but 90% of it is just for the gui mechanics (which I kept as rough as possible but still) so i won't explain all of it. The only important bits were the snippets shown above (which are included in the fully functional example below).
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