Concurrent work queues, less native async_send transitions#522
Concurrent work queues, less native async_send transitions#522benaadams wants to merge 2 commits into
Conversation
afae0fe to
d42a615
Compare
There was a problem hiding this comment.
I'm pretty sure there is a race here.
What if we don't call uv_async_send because the loop is apparently not idle when in fact the loop is merely finishing up? It's possible that _workQueue.IsEmpty returns true, but before _loopIdle is actually set to true, new work is enqueued and WakeUpLoop is called.
There was a problem hiding this comment.
Thought about this for a while; only performant way I can think of is to hit it with a sledgehammer. Changed how OnPost works.
|
There are basically two things we need to determine before merging this PR. Whether or not using a concurrent queue is faster than swapping normal queues inside a lock when consuming and always locking when adding. I think we should separately measure the impact of tracking |
|
The queue issue is all the writes contending on the lock rather than the swapping; which is probably quite efficient - though the writes also contend with the swap. The
Also validation on the Safehandles, the return values and the jit not being able to optimize the native call to anything better, inline it etc; and that's ignoring whatever libuv actually does with the call vs checking a bool :) |
|
i.e. on the swapping if it was a single writer and single reader; rather than many writers and one reader then the swap on a regular |
|
dev: benaadams/work-queue-merged: The removed locks do seem ever-so-slightly faster, and I personally don't see any race condition in this PR. Still, when I forwarded this PR out to @GrabYourPitchforks (best writer of lock-free code I know) to verify the correctness, his first response is it really worth removing the locks which make this obviously correct. I'm inclined to agree. The locks make me much more warm and fuzzy inside since it's easier for me to reason about than access to a volatile variable. |
|
Was this a comparison of current dev (faster); to branch (older)? Regardless, this would probably be an unsensible time to merge it* *As I imagine people will freeze to the RTM in production so as you and @davidfowl had mentioned previously; stability and security (or fixes for bad perf; rather than to make great perf better 😁 ) |
|
No. I merged this change into dev and then ran the test. I'm glad you agree. Like I said, I think this change is good, but I don't want any uncertainty. |
Process queues till complete
Remove the high contention locks
Reduce the calls to native
async_sendwhen not required (e.g. loop is currently processing).From #519