Jump to content

Detecting CPU usage


Gio
 Share

Recommended Posts

I have been wondering... In my web app I have some non-important tasks that are CPU-intensive and that I would like to run when the CPU is not doing much.

Can you think of a good way of detecting current CPU usage? The best solution that I can think of is measuring the time between requestAnimationFrame calls, but that only gives me a very rough indication of how busy the CPU is, as it is also a result of what the GPU is doing, and wouldn't give me any indication at all if my app was running faster than the system's vsync rate.

Do you have any other ideas?

Link to comment
Share on other sites

You can try this: after each frame, check how many spare milliseconds you have before the next frame. So if rendering a frame took 10 seconds, you have 16 - 10 = 6 milliseconds left to do some additional work. You should have periodic checks in your code and when you exceed the time limit, you'll save temporary results and exit.

Link to comment
Share on other sites

Pretty sure there is no decent way of getting this information from the browser. As you say, measuring the rendering performance gives you some indication of how much idle time, but measuring just the time between raf (the framerate) only gives you an indication that you're maybe doing too much and your fps is suffering, measuring the time your probably synchronous render function/s takes gives you an idea of how much spare time per raf tick you have but does not account for everything else going on.

I guess if you strictly delineate rendering and logic functions you could test how long each one took to run, but, sounds fiddly and unreliable.

Why not use web workers though? if the tasks are cpu-intensive let the OS handle juggling the CPU, or additional threads etc etc, and get your processing done away from your JS thread rather than squeezing it into the same main JS thread.

Link to comment
Share on other sites

Thanks for the tips guys.

To clarify and add some more restrictions: unfortunately this is not a game where things happen at set intervals, it's a (very complex) web app where there are both things happening at set intervals and lots of transactional (user-initiated) calculations that can happen at any time.

Webworkers are a good idea, but the amount of work that needs to be done on the main thread to kick off the web workers (gathering all the data and sending it to a task) is what I'm worried about.

Ideally I'd like to find a method to say "it looks like the user is just staring at the screen right now, they aren't actually doing anything or waiting for some expensive calculation to complete, it's a good time to run some of those tasks". But I'd need to do so without having to add code to each possible user-initiated function call, because I have literally hundreds of those. And when I add new ones, I'll forget to add this profiling code there too.

What do you think of something like this, in addition to timing request animation frame?

var before = performance.now();
setTimeout(function()
{
    var after = performance.now();
    if (after - before < 3)
    {
        // the main thread is not too busy
    }
}, 0);

 

Link to comment
Share on other sites

Rather than trying to guess at CPU occupancy, you may want to consider monitoring the user instead. Your code could implement a small event listener for keyboard, mouse, and touch events. Then set a timer that runs your task after x millisecs. Once the timer is set, restart it whenever an I/O event is detected. So, your task will only run after the user has been idle for x millisecs.

That still leaves accounting for your other higher priority tasks that run at set intervals, but it shouldn't be too difficult to improvise a generic solution that ensures your low priority task doesn't try to run at a time that would conflict with those tasks.

I agree with Matt... If your task is low priority and CPU intensive then it sounds like a good candidate to run on a web worker. Even if gathering the data is a bit of work, it is presumably significantly less work than running the task itself (which can now run on a separate core when processed by a web worker). Perhaps the data can be restructured in a way that makes it both easily usable by the main process and easy to send to the web worker.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...