Subject: Re: [boost] Futures vs async_result (was: Re: [afio] AFIO review postponed till Monday)
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2015-07-25 11:07:35
On 25 Jul 2015 at 2:32, TONGARI J wrote:
> If async_result can only deal with callbacks, I'd agree with you, but as
> already mentioned, it's also capable of futures, just replace the callback
> with placeholder like afio::use_future, for example.
> I don't know how afio is implemented internally, if using future as its
> primitive API does provide performance benefit, then I think it's fine to
> just expose the future API, however, if it adds more performance penalty
> than callback API, then I think it's conflict with the C++ philosophy - you
> don't pay for what you don't use.
> Using the proposed `await` with the asio style callback can provide
> zero-overhead synchronization as I shown you before, not a single
> lock/atomic nor dynamic allocation is needed, while using lightweight
> future, you still need to pay for atomic op & dynamic allocation when
> chaining the continuations (correct me if I'm wrong).
On completion, lightweight futures costs exactly two atomic XCHG to
signal and execute continuations (about 40 CPU cycles). It only calls
deallocation, one per continuation, after all other processing is
completed. The distance between ASIO calling the AFIO completion
handler and future continuations being invoked is likely less than
150 CPU cycles.
The above is a good example of why zero overhead completion handlers
is unimportant for file and filesystem where any operation at all is
going to cost > 100 microsecond. ASIO maxes out at about 0.365
microseconds per dispatch amortised. Lightweight future-promise costs
about 0.051 microseconds, so that's adding a 14% overhead, and that's
at least twice as lightweight as STL future-promise. If your
operation costs 100 microseconds, the overhead of a lightweight
future-promise is therefore 0.05%.
If you were talking about merely chaining pure coroutines, or even
socket i/o where *reaction* *time* to a recv() is the important
factor rather than overall throughput, I'd get your point entirely.
However with file and filesystem reaction time is not remotely
important at all because it's overall latency and throughput which
matters, not the time between when an i/o completes and you do
something with it.
My personal opinion is that for 99% of anyone doing async file or
filesystem that the choice of lightweight future promise as the
completion mechanism chosen is just not an issue. Hence the choice to
use them over async_result because they are what the STL has chosen
as the standard async notiifcation mechanism, and are therefore
unsurprising to most C++ programmers.
I also hear rumours that the Networking TS may yet enforce futures
for all networking, so the choice of futures by AFIO should not be
-- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk