3 ms·
> 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 timin
by 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.
- mehrdadn 6y ago> with no guarantee how often that work was going to appear. But you don't need (and should neither need nor want!) such a guarantee to do this the way I'm saying! It sounds like you might just be unfamiliar with overlapped I/O? ReadFile(), WSARecvMsg(), etc. all take OVERLAPPED structures that let you pass a HANDLE to an event object that gets signaled. There's also RegisterWaitForSingleObject, WSAAsyncSelect, WSAEventSelect, CreateIoCompletionPort... you name it. Heck, if you just have a thread select() the old-fashioned way, I think it should still wake up when the data comes, without introducing a delay at all. Nowhere should it matter how fast the data is coming, or to force you to wait more than you need to. Am I missing something?
- vardump 6y ago> Am I missing something? I think what you're missing is that all of the overlapped I/O scenarios completions you describe all originate from a hardware interrupt from some device, like a network adapter. We were talking about timing, not about waiting for I/O completion.
- mehrdadn 6y ago> I think what you're missing is that all of the overlapped I/O scenarios completions you describe all originate from a hardware interrupt from some device, like a network adapter. The comment literally says "packets came in from client machines". And they wanted to service these immediately, not 16ms later. Which is exactly what I'm describing. Timing requirements don't arise out of the void. Either they're externally mandated based on the wall clock (which is generally for human-oriented things like multimedia) in which case you should probably use something like a periodic multimedia timer, or they're based on other internal events (I/O, user input, etc.) that you can act on immediately. In neither case does Sleep() seem like the right solution, regardless of its accuracy... Very few real-world exceptions exist to this. In fact the only example I can think of off the top of my head (barring ones whose solution is busy-looping) is "I need to write a debugger that waits for a memory location to change and lets me know ASAP", in which case, I guess polling memory might be the way to go? But it would seem you would want event-based actions...