Page 1 of 1

Posted: Fri Mar 09, 2007 12:58 am
by netmaestro
I knocked together a little try based on GetProcessTimes_() which seems to work. It could probably be modified/improved, and there are other ways to accomplish it. I've included a little test program that uses around 3% CPU to test with, you can tweak the test prog to use more and see it change, comparing it to taskmanager. So far it's all correct here.

Code: Select all

;###################################################################################################################

Global gCurrentUsage.d

Procedure MonitorCPU(void)
  creation.FILETIME
  exit.FILETIME
  kernel.FILETIME
  user.FILETIME
  
  sysinfo.SYSTEM_INFO
  GetSystemInfo_(@sysinfo)
  numprocs = sysinfo\dwNumberOfProcessors

  h = OpenProcess_(#PROCESS_QUERY_INFORMATION, #False, GetCurrentProcessId_())  
  GetProcessTimes_(h,@creation,@exit,@kernel,@user)
  oldkernel=kernel\dwlowdatetime
  olduser=user\dwlowdatetime
  Delay(500)
  
  Repeat
    GetProcessTimes_(h,@creation,@exit,@kernel,@user)
    gCurrentUsage.d = ((((user\dwlowdatetime-olduser)+(kernel\dwlowdatetime-oldkernel))/500)/100)/numprocs
    olduser=user\dwlowdatetime
    oldkernel=kernel\dwlowdatetime    
    Delay (500)
  ForEver
EndProcedure

;###################################################################################################################


; Little test program - shows around 3% here, same as task mgr and debugger's CPU monitor

CreateThread(@MonitorCPU(),0)

InitSprite()
OpenWindow(0,0,0,640,480,"CPU Load Test",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(0),0,0,640,480,0,0,0)

CreateSprite(0, 128,128, #PB_Sprite_Texture)
StartDrawing(SpriteOutput(0))
  Box(0,0,128,128,#Red)
StopDrawing()
InitSprite3D()
CreateSprite3D(0,0)
CreateSprite3D(1,0)
CreateSprite3D(2,0)

Repeat
  ClearScreen(0)
  StartDrawing(ScreenOutput())
    DrawText(0,0,"CPU Usage: "+StrD(gCurrentUsage,2), #White, #Black)
  StopDrawing()
  Start3D()
    RotateSprite3D(0,1,1)
    RotateSprite3D(1,1,1)
    RotateSprite3D(2,1,1)
    DisplaySprite3D(0,100,100)
    DisplaySprite3D(1,250,100)
    DisplaySprite3D(2,400,100)
  Stop3D()
  FlipBuffers()
  Delay(1)
  ev = WindowEvent()
Until ev = #WM_CLOSE
You can put a timeBeginPeriod_(1) before the main loop and timeEndPeriod_(1) at the end and the CPU load goes to around 43% here, shown same in this proc as task mgr and CPU monitor utils.

This would actually be useful to make into a library and call it in your WIP projects to keep an eye on your CPU load, then you could take it out at release. I might make a little sticky window with a dial or something, could be fun.

Posted: Mon Apr 23, 2007 11:19 am
by dell_jockey
Hi,

I've added exponential smoothing to the routine above. The exponential moving average (EMA) is taken over the last #EMA_Samples, in this case an EMA over the last 20 samples that were taken with the original thread executing interval of 500ms. Effectively, you end up with an EMA over the last 10 seconds.

Enjoy!


Code: Select all

;################################################################################################################### 

Global gCurrentUsage.d

#EMA_Samples = 20 

Procedure.d EMA_smoothing(raw.d, samples.w)
  Static Alpha.d 
  Protected CurrentEMA.d
  Static PriorEMA.d
  
  Alpha.d = 2 / (samples.w + 1)
  CurrentEMA.d = priorEMA.d + (Alpha.d * (raw.d - priorEMA.d))
  PriorEMA.d = CurrentEMA.d
  
  ProcedureReturn CurrentEMA.d

EndProcedure


Procedure MonitorCPU(void) 
  creation.FILETIME 
  exit.FILETIME 
  kernel.FILETIME 
  user.FILETIME 
  
  sysinfo.SYSTEM_INFO 
  GetSystemInfo_(@sysinfo) 
  numprocs = sysinfo\dwNumberOfProcessors 

  h = OpenProcess_(#PROCESS_QUERY_INFORMATION, #False, GetCurrentProcessId_())  
  GetProcessTimes_(h,@creation,@exit,@kernel,@user) 
  oldkernel=kernel\dwlowdatetime 
  olduser=user\dwlowdatetime 
  Delay(500) 
  
  Repeat 
    GetProcessTimes_(h,@creation,@exit,@kernel,@user) 
    rawCurrentUsage.d = ((((user\dwlowdatetime-olduser)+(kernel\dwlowdatetime-oldkernel))/500)/100)/numprocs
    gCurrentUsage.d = EMA_smoothing(rawCurrentUsage.d, #EMA_Samples)
    olduser=user\dwlowdatetime 
    oldkernel=kernel\dwlowdatetime    
    Delay (500)
  ForEver 
EndProcedure 

;################################################################################################################### 


; Little test program - shows around 3% here, same as task mgr and debugger's CPU monitor 

CreateThread(@MonitorCPU(),0) 

InitSprite() 
OpenWindow(0,0,0,640,480,"CPU Load Test",#PB_Window_ScreenCentered|#PB_Window_SystemMenu) 
OpenWindowedScreen(WindowID(0),0,0,640,480,0,0,0) 

CreateSprite(0, 128,128, #PB_Sprite_Texture) 
StartDrawing(SpriteOutput(0)) 
  Box(0,0,128,128,#Red) 
StopDrawing() 
InitSprite3D() 
CreateSprite3D(0,0) 
CreateSprite3D(1,0) 
CreateSprite3D(2,0) 

Sprite3DQuality(1)

Repeat 
  ClearScreen(0) 
  StartDrawing(ScreenOutput()) 
    DrawText(0,0,"CPU Usage: "+StrD(gCurrentUsage,2)+"%", #White, #Black) 
  StopDrawing() 
  Start3D() 
    RotateSprite3D(0,1,1) 
    RotateSprite3D(1,1,1) 
    RotateSprite3D(2,1,1) 
    DisplaySprite3D(0,100,100) 
    DisplaySprite3D(1,250,100) 
    DisplaySprite3D(2,400,100) 
  Stop3D() 
  FlipBuffers() 
  Delay(1) 
  ev = WindowEvent() 
Until ev = #WM_CLOSE 

Re: Get CPU utilization by Process

Posted: Thu Nov 05, 2015 3:31 pm
by Tenaja
The help file does not have replacements for CreateSprite3D etc. easy to find. Not in search, not in history. Any of you graphics guys know how to fix Netmaestro's code?

Thanks.

Re: Get CPU utilization by Process

Posted: Thu Nov 05, 2015 5:20 pm
by BasicallyPure
You can just use regular sprites.
Here is dell_jockey's code modified to work with regular sprites.
PB 5.40 LTS compatible.

Code: Select all

;################################################################################################################### 

Global gCurrentUsage.d

#EMA_Samples = 20 

Procedure.d EMA_smoothing(raw.d, samples.w)
  Static Alpha.d 
  Protected CurrentEMA.d
  Static PriorEMA.d
  
  Alpha.d = 2 / (samples.w + 1)
  CurrentEMA.d = priorEMA.d + (Alpha.d * (raw.d - priorEMA.d))
  PriorEMA.d = CurrentEMA.d
  
  ProcedureReturn CurrentEMA.d

EndProcedure


Procedure MonitorCPU(void) 
  creation.FILETIME 
  exit.FILETIME 
  kernel.FILETIME 
  user.FILETIME 
  
  sysinfo.SYSTEM_INFO 
  GetSystemInfo_(@sysinfo) 
  numprocs = sysinfo\dwNumberOfProcessors 

  h = OpenProcess_(#PROCESS_QUERY_INFORMATION, #False, GetCurrentProcessId_())  
  GetProcessTimes_(h,@creation,@exit,@kernel,@user) 
  oldkernel=kernel\dwlowdatetime 
  olduser=user\dwlowdatetime 
  Delay(500) 
  
  Repeat 
    GetProcessTimes_(h,@creation,@exit,@kernel,@user) 
    rawCurrentUsage.d = ((((user\dwlowdatetime-olduser)+(kernel\dwlowdatetime-oldkernel))/500)/100)/numprocs
    gCurrentUsage.d = EMA_smoothing(rawCurrentUsage.d, #EMA_Samples)
    olduser=user\dwlowdatetime 
    oldkernel=kernel\dwlowdatetime    
    Delay (500)
  ForEver 
EndProcedure 

;################################################################################################################### 


; Little test program - shows around 3% here, same as task mgr and debugger's CPU monitor 

CreateThread(@MonitorCPU(),0) 

InitSprite() 
OpenWindow(0,0,0,640,480,"CPU Load Test",#PB_Window_ScreenCentered|#PB_Window_SystemMenu) 
OpenWindowedScreen(WindowID(0),0,0,640,480,0,0,0) 

CreateSprite(0, 128, 128);CreateSprite(0, 128,128, #PB_Sprite_Texture) 
StartDrawing(SpriteOutput(0)) 
  Box(0,0,128,128,#Red) 
StopDrawing() 
;InitSprite3D() 
CopySprite(0,1);CreateSprite3D(0,0) 
CopySprite(0,2);CreateSprite3D(1,0) 
CopySprite(0,3);CreateSprite3D(2,0) 

;Sprite3DQuality(1)

Repeat 
  ClearScreen(0) 
  StartDrawing(ScreenOutput()) 
    DrawText(0,0,"CPU Usage: "+StrD(gCurrentUsage,2)+"%", #White, #Black) 
  StopDrawing() 
  ;Start3D() 
    RotateSprite(1,1,#PB_Relative);RotateSprite3D(0,1,1) 
    RotateSprite(2,1,#PB_Relative);RotateSprite3D(1,1,1) 
    RotateSprite(3,1,#PB_Relative);RotateSprite3D(2,1,1) 
    DisplaySprite(1,100,100);DisplaySprite3D(0,100,100) 
    DisplaySprite(2,250,100);DisplaySprite3D(1,250,100) 
    DisplaySprite(3,400,100);DisplaySprite3D(2,400,100) 
  ;Stop3D() 
  FlipBuffers() 
  Delay(1) 
  ev = WindowEvent() 
Until ev = #PB_Event_CloseWindow;#WM_CLOSE