7 ms·
The resolution or behavior of other APIs is beside my point. I'm saying, even if in an ideal world Sleep did wait exactly how much you told it to, I don't get w
by mehrdadn 6y ago
The resolution or behavior of other APIs is beside my point. I'm saying, even if in an ideal world Sleep did wait exactly how much you told it to, I don't get why you would feel justified in using it to trigger something every N ms. Even if N = 16ms. Your code itself might takes 3ms to run one time, 6ms another time, or 9ms a third time. Sleeping 16ms every time just won't get you periodic behavior even if Sleep is perfectly accurate. Right? i.e. Sleep() just seems like the wrong API regardless of everything else...
- deleted 6y ago[deleted]
- gambiting 6y agoI don't think I understand your concern here. The idea wasn't to do something every N millis, the loop was "process work, if there isn't any more work to do, sleep(1), repeat". Like you said, the "work" part can take any amount of time - but when it does run out, the thread needs to sleep/wait. We have experimented with several APIs for this, including the methods you suggested, and it had no effect on actual time spent waiting for more work to appear - sleep(1) had the exact same effect as simply using WaitForObject and the work producer signalling on that object - the times were literally identical. Edit: reading your comment again I think I see the misunderstanding - sleep wasn't used to do something periodically, if that's what you want to do then indeed, sleep is the wrong tool.
- mehrdadn 6y agoI guess I'm not understanding your use case, if it's not periodic invocation. Why you were calling Sleep(1)? Why was a 16ms sleep problematic in that case?
- vardump 6y agoAgain. Sleep(1) is just a shorthand to discuss about this topic. Exact same behavior affects every other Windows timing mechanism as well.
- gambiting 6y agoBecause once a thread is done with all available work, it has to sleep/wait, the only other alternative is busy waiting(awful idea). So if you see ok, there is no more available work, and call sleep(1), and some more work comes in 2ms later, that work might not be picked up for a whole next 14ms. That is the core of the problem. Like, you are focusing on the sleep(1) part too much - what I want to do is "wait until there is more work available to process, and then wake up and start processing as soon as physically possible". On Windows the "as soon as physically possible" part is unfortunately 16ms in most cases, and that's just not acceptable for something as precise as audio work.
- mehrdadn 6y ago> what I want to do is "wait until there is more work available to process" If this is merely to free up CPU when you have no work to do, then the actual timing of 1ms vs 16ms doesn't seem like the issue, right? Shouldn't you be instead waiting on a condition that gets set when work is queued? Like an event object, or an I/O completion port, or something that indicates work is ready? Instead of polling for the condition? > On Windows the "as soon as physically possible" part is unfortunately 16ms in most cases, and that's just not acceptable for something as precise as audio work. Aren't you contradicting yourself here? If you're doing audio don't you want periodic multimedia timers? Which are built for this purpose and actually also do deliver the resolution you need?
- gambiting 6y ago>>Shouldn't you be instead waiting on a condition that gets set when work is queued? Like an event object, or an I/O completion port, or something that indicates work is ready? Instead of polling for the condition? Again, as I said multiple times - the WaitForObject won't wake up any sooner than Sleep(1) will. Only a real proper hardware interrupt could wake up quicker - but that requires special hardware that just wasn't available in that scenario. If it's easier to think about that way, then please assume I said that WaitForObject "sleeps" way more than necessary due to the low timer resolution on Windows. >>Aren't you contradicting yourself here? If you're doing audio don't you want periodic multimedia timers? No, because like I said at the very beginning, I was writing a server application processing audio coming in from the clients. So essentially every time packets came in from client machines they had to be processed and sent back - that's why I had multiple threads "waiting" for work and they had to pick it up as soon as possible, with no guarantee how often that work was going to appear. It's not the same as picking up audio from a hardware device on a client machine which yes, has to be done periodically. It's a simple producer/consumer queue problem, but with it being audio data, 16ms wait times to process packets was not acceptable - pretty much no other work is that time sensitive(except for video I guess), yet it wasn't the kind of work that has to be done on a specific periodic timer.
- vardump 6y agoCorrect. You've clearly had to deal with precise Windows timing as well! To add, it's pretty shocking there's nothing better in the kernel mode either. It's just as bad as in the user mode. You actually have to generate an interrupt on a hardware device (like a PCI card) to get good timing performance out of Windows!
- eska 6y agoYou shouldn't use time in this scenario at all, but wait on a condition. It's unreasonable to expect a non-realtime kernel to offer this precision with timers. Doing serious audio work on non-realtime kernels, you have to expect such issues.
- gambiting 6y agoAgain, on windows using waits on kernel objects has the exact same result. A signaled object will only wake up the waiting thread at the timer interrupt, so it doesn't matter if you use sleep(1) and check if there is work to do, or if you use a kernel object and wait on it - the time spent sleeping will be exactly identical.
- vardump 6y agoWell, there's a fine line here. Correct me if I'm wrong, but if it's hardware based IRP completion (like DMA done, network card received a packet or whatever), your thread could wake up very soon after I/O completes, long before the next timer tick. But this is not something you can use for timing, unless of course your hardware is built to do so.
- Dylan16807 6y agoThe wait time will be the same but the amount of wasted CPU won't. It's not a lot but it adds up. If it's only on your servers then whatever, but if the code goes to clients then please wait on an event.