I set up my PIT for sleep and speaker.
With the channel 0 running at ~1000Hz, it is causing a great overhead here.
Before implementing PIT, clearing/re-rendering my terminal was instantaneous.
Now, the overhead is so great that it is noticeably visually slow. Slow enough for human reaction times.
Is there any optimizations I can do here to decrease the PIT overhead?
PIT interrupt significantly overheads the kernel
PIT interrupt significantly overheads the kernel
Skylight: https://github.com/austanss/skylight
I make stupid mistakes and my vision is terrible. Not a good combination.
NOTE: Never respond to my posts with "it's too hard".
I make stupid mistakes and my vision is terrible. Not a good combination.
NOTE: Never respond to my posts with "it's too hard".
Re: PIT interrupt significantly overheads the kernel
Measure first: Is it really the PIT slowing you down? Is your interrupt code that slow? One way to measure this would be calculate the difference in TSC for one run through your redraw routine and simultaneously add up the TSC differences running through your PIT handler. The result should be a rough estimate of "it takes X cycles to redraw the screen, Y of which spent in the PIT handler".
If so, possible optimizations to consider: Don't use a fixed tick rate. I have a timer system. Every timer has a deadline and a callback. All timers are organized into a priority queue, sorted by deadline. Whenever the CPU goes idle, the time to the next deadline is calculated and then the interrupting timer (typically LAPIC timer in my case, would be PIT in your case) is set up to wake the CPU when the deadline expires. Then all the timer callbacks are run for the timers that expired while the CPU slept (and those timers are removed from the p-queue). And if someone wants to know the time I return the value of a hardware counter (adjusted and normalized, obs.) Therefore I have no need for a fixed-rate interrupt, and my CPU can happily do more things in one go.
A preemption interrupt is only needed of more than once process is ready to go on the current CPU, and that happens rarely. And is handled with another timer, that sets the preemption flag.
If so, possible optimizations to consider: Don't use a fixed tick rate. I have a timer system. Every timer has a deadline and a callback. All timers are organized into a priority queue, sorted by deadline. Whenever the CPU goes idle, the time to the next deadline is calculated and then the interrupting timer (typically LAPIC timer in my case, would be PIT in your case) is set up to wake the CPU when the deadline expires. Then all the timer callbacks are run for the timers that expired while the CPU slept (and those timers are removed from the p-queue). And if someone wants to know the time I return the value of a hardware counter (adjusted and normalized, obs.) Therefore I have no need for a fixed-rate interrupt, and my CPU can happily do more things in one go.
A preemption interrupt is only needed of more than once process is ready to go on the current CPU, and that happens rarely. And is handled with another timer, that sets the preemption flag.
Carpe diem!
-
- Member
- Posts: 5568
- Joined: Mon Mar 25, 2013 7:01 pm
Re: PIT interrupt significantly overheads the kernel
Are you seeing this on bare metal or inside a VM? Timing tends to be a bit funny in VMs, especially with slow old hardware like the PIT.
Re: PIT interrupt significantly overheads the kernel
Tested only in QEMU. I'm having issues with my (non-custom) bootloader not loading my kernel correctly on bare metal.Octocontrabass wrote:Are you seeing this on bare metal or inside a VM? Timing tends to be a bit funny in VMs, especially with slow old hardware like the PIT.
Skylight: https://github.com/austanss/skylight
I make stupid mistakes and my vision is terrible. Not a good combination.
NOTE: Never respond to my posts with "it's too hard".
I make stupid mistakes and my vision is terrible. Not a good combination.
NOTE: Never respond to my posts with "it's too hard".
Re: PIT interrupt significantly overheads the kernel
It's possible that your interrupts are happening too regularly, and that takes priority over everything else. It depends on the PIT frequency you set. That said, the PIT isn't very high-frequency to begin with, so it's just an idea. But, tweaking values of the PIT can incur VMEXITs so make sure you program it as little as possible.
An example: When you have real timer system that uses (for example) APIC timer as backend, you will find that its cheaper to not reprogram the APIC timer if you delete a timer, and that timer happens to be in the front. Instead just letting it trigger, and then doing the right thing is cheaper, because anything can happen in that time. You could be deleting one timer, and then creating a new timer that is earlier, in which case the MMIO writes from adjusting the time to next timer from the deletion of another timer is just a waste of resources. Such lazy schemes when dealing with hardware can be advantageous. Another example is when you are accidentally late in handling timers, and avoiding the re-programming turned out to be advantageous because you triggered multiple timers, without having to do any re-programming.
So, as for your PIT problem: Count the number of interruptions, and see if the number is way too high, and if not, try to count how much you are re-programming the PIT - and then avoid that.
An example: When you have real timer system that uses (for example) APIC timer as backend, you will find that its cheaper to not reprogram the APIC timer if you delete a timer, and that timer happens to be in the front. Instead just letting it trigger, and then doing the right thing is cheaper, because anything can happen in that time. You could be deleting one timer, and then creating a new timer that is earlier, in which case the MMIO writes from adjusting the time to next timer from the deletion of another timer is just a waste of resources. Such lazy schemes when dealing with hardware can be advantageous. Another example is when you are accidentally late in handling timers, and avoiding the re-programming turned out to be advantageous because you triggered multiple timers, without having to do any re-programming.
So, as for your PIT problem: Count the number of interruptions, and see if the number is way too high, and if not, try to count how much you are re-programming the PIT - and then avoid that.