4 ms·
I think you misunderstood. If you want "timing sensitive processing", that's what you can and should expect to use events or multimedia timers for. That way you
by mehrdadn 6y ago
I think you misunderstood. If you want "timing sensitive processing", that's what you can and should expect to use events or multimedia timers for. That way you can actually expect to meet timing guarantees. Using Sleep() and depending on it for correctness in such situations (regardless of its accuracy) is kind of like using your spacebar to heat your laptop... it doesn't seem like the right way to go on its face, even if there was something to guarantee it would work: https://xkcd.com/1172/ https://xkcd.com/1172/
- vardump 6y ago> that's what you can and should expect to use events or multimedia timers for I don't want to use a deprecated API call, timeSetEvent. > Using Sleep() and depending on it... Absolutely no one was using Sleep for timing. It just used to be that all Windows timer mechanisms are really the same thing, and Sleep(1) was an easy way to quickly test actual timing precision. Obviously Windows 10/2004 changed all this.
- jlokier 6y ago> I don't want to use a deprecated API call, timeSetEvent. That's not what dataflow is saying to use. The phrase is "events or timers", not "timer events". gambiting describes this scenario: The hardware (network) does interrupt the CPU and supplies an incoming packet to the receiver thread, which does not use a timer. Then the receiver thread wants to send it to a worker thread. It sounds like gambiting's implementation has the worker threads polling a software queue using a sleep-based timer, to pick up work from the receiver thread. Unless there's something not being said in that picture, the receiver should be sending an event to a worker thread to wake the worker instantaneously, rather than writing to memory and letting the workers get around to polling it in their own sweet, timer-dependent, unnecessarily slow time. Given that it's described as audio data which must be processed with low latency, it seems strange to insert an avoidable extra 1ms delay into the processing time... This is kind of the point of events (and in windows, messages; not timers or timer-events). So that one thread can wake another thread immediately. The whole "if your hardware supports it" reply seems irrelevant to the scenario gambiting has described, as the only relevant hardware sounds like network hardware. Either that's interrupting on packet arrival or it isn't, but either way, a sleep(1) loop in the worker threads won't make packet handling faster, and is almost certainly making the responses slower than they need to be, no matter which version of Windows and which timer rate.(+) (+) (Except in some exotic multi-core setups, and it doesn't sound like that applies here).
- gambiting 6y ago>>Unless there's something not being said in that picture, the receiver should be sending an event to a worker thread to wake the worker instantaneously I have kind of answered this before - you can signal on an event from the receiver thread, and it doesn't wake up the waiting threads instantaneously, even if they are waiting on a kernel-level object. The WaitForObject will only return at the next interrupt of a system timer.....so exactly at the same point when a Sleep(1) would have woken up too. There is no benefit to using the event architecture, because for those sub-16ms events it doesn't actually bypass the constraint of the system timer interrupt. >>So that one thread can wake another thread immediately. The problem here is that the immediate part isn't actually immediate, that's the crux of the whole issue.
- mehrdadn 6y ago> you can signal on an event from the receiver thread, and it doesn't wake up the waiting threads instantaneously, even if they are waiting on a kernel-level object. This isn't normally the case. You should expect this not to be the case because programs would be insanely inefficient if this happened. My suspicion is there was something else going on. For example, maybe all CPUs were busy running threads (possibly with higher priority?) and so there was no CPU a waiting worker could be scheduled on. But it's not normally what's supposed to happen; it's pretty easy to demonstrate threads get notified practically immediately and don't wait for a time slice. Just run this example and you'll see threads getting notified in a few microseconds: #include <process.h> #include <tchar.h> #include <Windows.h> LARGE_INTEGER prev_time; unsigned int CALLBACK worker(void *handle) { LARGE_INTEGER pc, pf; QueryPerformanceFrequency(&pf); WaitForSingleObject(handle, 5000); QueryPerformanceCounter(&pc); _tprintf(_T("%lu us\n"), (pc.QuadPart - prev_time.QuadPart) * 1000000LL / pf.QuadPart); return 0; } int _tmain(int argc, TCHAR *argv[]) { HANDLE handle = CreateEvent(NULL, FALSE, FALSE, NULL); uintptr_t thd = _beginthreadex(NULL, 0, worker, handle, 0, NULL); Sleep(100); QueryPerformanceCounter(&prev_time); SetEvent(handle); WaitForSingleObject((HANDLE)thd, INFINITE); }
- jlokier 6y agoFrom my other comment here, I think you have a race condition or something like that in your code, or as the peer comment suggests scheduling contention on the CPU, which is causing this effect in your test. For a real-world measurement, see: >> "Windows event object was used but it takes 6-7us from SetEvent() to WaitForSingleObject() return on my machine The person measured 6-7 microseconds. The system timer is not interrupting that fast.