Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How fast is your OSes keyboard input?
#1
Inspired by Phil's topic about _KEYHIT (Trying to understand keyhit function (qb64phoenix.com), I couldn't help but become curious myself about how often do we need to poll _KEYHIT?  Phil's original routine had a limitless loop polling for key events, which is something that I personally *never* think is a good idea.  Unthrottled loops are for processing things inside a program -- not for waiting for the user to complete some interaction!  What happens if the user suddenly has someone show up at their door at the moment it enters one of these input-feedback loops?  They're not there to actually press a key, so what you're dealing with is basically nothing much more than a DO: LOOP which is going to use 100% CPU power, run your PC hot, kick the fans in, use more electricity, and do *NOTHING* beneficial for you!!

Obviously, there should be some sort of limit in how often we check the keyboard for an input event, so my mind instantly begins to ask, "How many times is enough to keep up with reading the buffer, as much as the OS writes to it?"  How often does your keyboard record a keypress, and how often does it report it to you?  Does it report those events every 1/10 second?  every 1/100th?  1/1000??

Honestly, I don't know!!

So, I wrote this little bit of code below to try and see how often my OS would report key events for me:

Code: (Select All)
Do
    Do
        k = _KeyHit
    Loop Until k > 0 'some key is pressed down to start the timer
    t## = Timer
    count = 0 'reset count between loops
    Do
        k = _KeyHit
        If k > 0 Then count = count + 1 'increase the count rate based on the keyboard repeat/limit cycle
    Loop Until Timer > t## + 1
    Print count; "in 1 second"
    _KeyClear
Loop Until k = 27


We start a loop, wait for a key to be pressed down to start a simple timer.  Then we count how many keydown events are reported in that second.  Finally, we report that number and clear the buffer to recount the process once again, until the user finally hits the ESC key to end the program.

For me, my keyboard on my laptop has a repeat rate of almost consistently 30 key hits per second.  (I get reports of 30 and then 31 and then 30 and then 31.... Which seems to be an artifact of rounding and floating point numbers in my opinion.)  I think if I set a DO LOOP like these to _LIMIT 30, there'd be almost no noticeable change in how this program works. 

Code: (Select All)
Do
    Do
        k = _KeyHit
        _Limit 30
    Loop Until k > 0 'some key is pressed down to start the timer
    t## = Timer
    count = 0 'reset count between loops
    Do
        k = _KeyHit
        If k > 0 Then count = count + 1 'increase the count rate based on the keyboard repeat/limit cycle
        _Limit 30
    Loop Until Timer > t## + 1
    Print count; "in 1 second"
    _KeyClear
Loop Until k = 27


Try the first program and see what type of results you get.  Try the second, with a _Limit 30 placed inside each loop and see if the performance changes much (if any at all) for you.  For me, there's absolutely no difference in performance, leading me to think that if I'm running a program with an endless _KEYHIT loop like these, then there's absolutely no reason for me to run them with anything faster than a _LIMIT 30 in them.  On my laptop at least, I don't seem to get keyhit events any faster than 30 times per second, so it really doesn't seem like I'd need to use CPU resources and run my program usage up beyond that point.

What I'm curious about now is other people's computers/OS.  How often does your system update and report a keyhit event?  Is there anyone who runs much higher with a repeat rate faster than 30 times per second?  _Limit 30 works fine for me, but would it be throttling down someone else's system too much??

Honestly, if I was going to code this for a working program, I'd probably just make it a _LIMIT 60, and say "Good enough!!" with it.  Twice what mine reports, so I figure that'll handle the majority of PCs out there and still not use an excessive amount of resources.  Anyone higher than that, can just sort the code out and tweak it themselves.  ;D
Reply
#2
For all my word processor routines, I use _LIMIT 30 for keyboard input, but for mouse driven routine, I sometimes need _LIMIT 60 for better performance.

Pete
Shoot first and shoot people who ask questions, later.
Reply
#3
Yeah for keys only 30 is fine but add the mouse and you'll usually want the mouse polled more often.
b = b + ...
Reply
#4
(08-09-2022, 04:54 PM)bplus Wrote: Yeah for keys only 30 is fine but add the mouse and you'll usually want the mouse polled more often.

But you generally handle mouse in its own loop, so it's not counted.


DO
   WHILE _MOUSEINPUT: WEND
   k = _KEYHIT
   ' process the input
   _LIMIT 30
LOOP
Reply
#5
Generally, I redraw background (if it's a constantly changing one) at the start of the loop, poll the mouse and the keys, handle what comes up then _Display and _Limit before the loop around.

Ehh, maybe saying same thing when I reread your code. I dont think of polling mouse or keys as a loop.
b = b + ...
Reply
#6
If I'm mouse dragging an object, while in a timed loop, I don't want _LIMIT 30. _LIMIT 60 or greater works better during the drag event.

Pete
Shoot first and shoot people who ask questions, later.
Reply
#7
I'm a fan of _LIMIT 30. My reasoning is more human than computer based. I always heard that old acetate film reels ran at 24 frames per second, and at that rate the human eye and brain perceived fluid motion from the individual frames. Thus I figured 30 was an even better number, and easily beyond our reaction and perception times. I generally don't perceive anything jerky or delayed in most of my programs, except if there is a definite bug in the works. 

I usually do a dual nested loop that grabs input on the inner one, whether keyboard or mouse, and that loop is limited and exited via an input flag each time a legitimate input is received and processed. The outer loop refreshes the display and has no limit as it's a one time thing and the input loop is re-entered. So 99.99...% of the time my programs are polling an INKEY$ and a quick call to Steve's MBS function at 30 loops per second. I have no issues leaving programs, like my harvesting database, running for many hours. Which they have to do.

Sometimes I'll notice a lag in some screen feature following a mouse cursor, but since I'm not a fast action game programmer, that scheme works fine in my programs. I haven't done any mouse dragging stuff yet to see if it causes issues.

P.S. After trying Steve's tests, I'd say I'm about right. The first yielded 30-31 just holding a key down and the second ran at a consistent 31.
DO: LOOP: DO: LOOP
sha_na_na_na_na_na_na_na_na_na:
Reply
#8
My laptop shows a slight difference. It's a consistent 32 in the first unconstrained loop test, and it fluctuates between 31 and 30 in the _limit 30 test.

On the movie question, 35mm film movies are indeed 24 frames per second, but each frame is projected twice, to prevent flicker. And too, motion portrayal can be very bad in some cases, so cameramen use all manner of tricks to make it look right. In live sports, TV uses 60 frames per second, even though TV gets by with 30 frames per second for normal material.

https://www.techhive.com/article/582731/...ndles.html

"Have you ever watched live sports on a streaming service such as Sling TV and thought it didn’t look quite right? Compared to cable, satellite, or over-the-air broadcast TV, streamed sporting events can look a bit choppy or jittery, making it harder to keep track of quick passes and fast breaks.

"The issue here is frame rate. Sports telecasts typically come in at a smooth 60 frames per second. But that higher frame rate isn’t a given with streaming services, where that same video might play at a choppier 30 frames per second. As this 60 fps vs. 30 fps comparison video on YouTube illustrates, frame rate is the difference between a lifelike picture and one that looks more like a scripted TV show."

I too would expect therefore that mice should be polled more like 60 Hz.

All sorts of interesting stuff on this subject.
Reply
#9
Getting 31 holding the button down on my laptop or remote keyboard. The first second can sometimes report as few as 5 reads. It depends on when you ask the computer?
Reply
#10
(08-11-2022, 03:02 PM)James D Jarvis Wrote: Getting 31 holding the button down on my laptop or remote keyboard.  The first second can sometimes report as few as 5 reads.  It depends on when you ask the computer?

There's two settings which apply for a key's repeat rate:  time until repeat, time between repeat.  

If you think about it for just a moment, it makes perfect sense.  You don't want someone who's a little slow and lethargic to slowly *tik* down on a key, and then have it repeat for them before they *tok* it back up.  There's an initial period for how long the key has to be down, before it starts to repeat.  You can access these controls in the "Keyboard Settings" in your control panel.

[Image: image.png]

quick print screen upload


So that first report counts the delay *before* repeat starts to kick in, and then the OS's repeat rate determines what the result will be after that, once it starts repeating the presses.

And that's why you're seeing the difference in the first round of figures and the rest when running the test.  Wink
Reply




Users browsing this thread: 4 Guest(s)