digitalmars.D - Zero timeout receive
- James Wirth (13/13) Apr 12 2013 The discussion:
- John Colvin (6/19) Apr 13 2013 Make a small test and time it. I personally wouldn't expect to
- James Wirth (10/35) Apr 15 2013 Im using wine on Linux to develop MS code (dont have an MS box)
- Sean Kelly (10/12) Apr 16 2013 might impact other receive performance. As a Java programmer I tend to ...
- James Wirth (4/19) Apr 18 2013 Many Thanks, I appreciate the "hand holding". Will use
- Sean Kelly (38/47) Apr 16 2013 http://forum.dlang.org/thread/mailman.426.1286264462.858.digitalmars-d@p...
The discussion: http://forum.dlang.org/thread/mailman.426.1286264462.858.digitalmars-d puremagic.com?page=9 implies that: receiveTimeout(dur!"msecs"(0), some-callback-function) is acceptable - meaning that no blocking occurs. A simple experiment verifies this - but I hesitate to use "undocumented" features. Some APIs would interpret the 0 as infinity. I also fear that placing such a nonblocking recieve into the main event loop of a GUI program would impact performance - it would also be non-generic. Is there a fast function which returns true just when the "mail box" is non-empty? Thanks
Apr 12 2013
On Saturday, 13 April 2013 at 01:26:16 UTC, James Wirth wrote:The discussion: http://forum.dlang.org/thread/mailman.426.1286264462.858.digitalmars-d puremagic.com?page=9 implies that: receiveTimeout(dur!"msecs"(0), some-callback-function) is acceptable - meaning that no blocking occurs. A simple experiment verifies this - but I hesitate to use "undocumented" features. Some APIs would interpret the 0 as infinity. I also fear that placing such a nonblocking recieve into the main event loop of a GUI program would impact performance - it would also be non-generic. Is there a fast function which returns true just when the "mail box" is non-empty? ThanksMake a small test and time it. I personally wouldn't expect to see much slowdown from the extra code invoked by receiveTimeout compared to the rest of a busy loop. However, either special casing receiveTimeout for 0 duration or introducing a new receiveNoBlock or similar would be good.
Apr 13 2013
On Saturday, 13 April 2013 at 08:54:03 UTC, John Colvin wrote:On Saturday, 13 April 2013 at 01:26:16 UTC, James Wirth wrote:Im using wine on Linux to develop MS code (dont have an MS box) so am not too confident of timing accuracy - however, I tried it in the really simple MS GUI library Im making, and it seems to work ok. Special casing receiveTimeout would introduce less name bloat but might impact other receive performance. As a Java programmer I tend to ignore slowdowns of 2:1 and as a Python programmer even 70:1 - but I could see that system programmers might disagree. Thanks for your thoughts.The discussion: http://forum.dlang.org/thread/mailman.426.1286264462.858.digitalmars-d puremagic.com?page=9 implies that: receiveTimeout(dur!"msecs"(0), some-callback-function) is acceptable - meaning that no blocking occurs. A simple experiment verifies this - but I hesitate to use "undocumented" features. Some APIs would interpret the 0 as infinity. I also fear that placing such a nonblocking recieve into the main event loop of a GUI program would impact performance - it would also be non-generic. Is there a fast function which returns true just when the "mail box" is non-empty? ThanksMake a small test and time it. I personally wouldn't expect to see much slowdown from the extra code invoked by receiveTimeout compared to the rest of a busy loop. However, either special casing receiveTimeout for 0 duration or introducing a new receiveNoBlock or similar would be good.
Apr 15 2013
On Apr 15, 2013, at 7:22 PM, James Wirth <jwirth1 suddenlink.net> wrote:=20 Special casing receiveTimeout would introduce less name bloat but =might impact other receive performance. As a Java programmer I tend to = ignore slowdowns of 2:1 and as a Python programmer even 70:1 - but I = could see that system programmers might disagree. Currently, receiveTimeout will call Condition.wait(n) for any wait time = passed. For a wait time of 0, this will be equivalent to a yield(), so = the calling thread will be suspended for a context switch if there are = other threads waiting to run. I could special case this to not wait at = all, but am inclined to say that the yield() effect is a good thing = here, as it helps concurrency.=
Apr 16 2013
On Tuesday, 16 April 2013 at 21:38:39 UTC, Sean Kelly wrote:On Apr 15, 2013, at 7:22 PM, James Wirth <jwirth1 suddenlink.net> wrote:Many Thanks, I appreciate the "hand holding". Will use receiveTimeout(0,...) without fear henceforth. I think yielding in the windows event thread will indeed benefit the application.Special casing receiveTimeout would introduce less name bloat but might impact other receive performance. As a Java programmer I tend to ignore slowdowns of 2:1 and as a Python programmer even 70:1 - but I could see that system programmers might disagree.Currently, receiveTimeout will call Condition.wait(n) for any wait time passed. For a wait time of 0, this will be equivalent to a yield(), so the calling thread will be suspended for a context switch if there are other threads waiting to run. I could special case this to not wait at all, but am inclined to say that the yield() effect is a good thing here, as it helps concurrency.
Apr 18 2013
On Apr 12, 2013, at 6:26 PM, James Wirth <jwirth1 suddenlink.net> wrote:The discussion: =20 =http://forum.dlang.org/thread/mailman.426.1286264462.858.digitalmars-d pur= emagic.com?page=3D9=20 implies that: receiveTimeout(dur!"msecs"(0), some-callback-function) =20 is acceptable - meaning that no blocking occurs. A simple experiment =verifies this - but I hesitate to use "undocumented" features. Some = APIs would interpret the 0 as infinity. Then consider it documented. receiveTimeout(0, =85) is intended to work = as it does currently. If you want it to block forever, use receive(=85).I also fear that placing such a nonblocking recieve into the main =event loop of a GUI program would impact performance - it would also be = non-generic. Is there a fast function which returns true just when the = "mail box" is non-empty? The receive calls are as lightweight as I can make them. In essence: 1. Walk a thread-local list of received messages looking for a match. = If found, pass to the callback, remove the message, and return. 2. Lock a shared list of recently received messages. If the list is = empty, block on a condition variable until a message is received, then = go to step 3. 3. Move all messages from the shared list to a local list and release = the lock. 4. Walk this new list of messages looking for a match. If found, pass = the callback, remove the message, append these new messages to the = thread-local list and return. 5. If no match, append these new messages to the thread-local list and = go to step 2. So if the message you want is already present in your local message = queue, receive doesn't even need to acquire a mutex. If not, it = acquires the mutex for just as long as it takes to move the new messages = from the shared list to the local list (basically reassigning a few = pointers). If no match anywhere, then it will block for as long as = indicated, either forever for receive() or until the timeout has elapsed = with receiveTimeout(). By the way, I just noticed that the receiveTimeout() version uses the = same timeout for each condvar wait when it should be reducing it on each = iteration to ensure that the maximum wait time is as indicated. This is = a bug and needs to be fixed. And because of how Condition is = implemented, this will mean a kernel call to determine time elapsed on = each iteration where a message was received before the timeout. So this = case at least will be a bit less optimal that what could be done = targeting Posix specifically.=
Apr 16 2013