Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does std::future spin-wait?

Before explaining the question in more detail, I'll note that the answer is obviously implementation dependent, so I'm primarily asking about libstdc++, but I would also be interested in hearing about libc++. The operating system is Linux.

Calling wait() or get() on a std::future blocks until the result is set by an asynchronous operation -- either an std::promise, std::packaged_task, or std::asyn function. The availability of the result is communicated through a shared state, which is basically an atomic variable: the future waits for the shared state to be marked as ready by the promise (or async task). This waiting and notification is implemented in libstdc++ via a futex system call. Granted that futexes are highly performant, in situations where a future expects to only wait for an extremely brief period (on the order of single microseconds), it would seem that a performance gain could be made by spinning on the shared state for a short time before proceeding to wait on the futex.

I have not found any evidence of such spinning in the current implementation, however, I did find a comment in atomic_futex.h at line 161 where I would expect to find such spinning:

// TODO Spin-wait first.

So my question is rather the following: Are there really plans to implement a spin-wait, and if so, how will the duration be decided? Additionally, is this the type of functionality that could eventually be specified through a policy to the future?

like image 443
Spectral Sequence Avatar asked Jan 30 '17 20:01

Spectral Sequence


1 Answers

I will answer the question: Does std::future::get() perform a spin-wait?

The answer for all of C++ is: It is an implementation detail. A conforming standard library might spin or it might not (in the same vein, std::mutex::lock() is allowed to spin). Will there be a mechanism for specifying if and how to spin in the future? The places to look are in std::experimental::future (coming to a full version of the Standard Library soon), boost::future (proving ground for what might later go into the standard), and hpx::future (performance-focused library with advanced facilities for future management). None of these have mechanisms for explicit specification of spinning, nor has there been discussion in meeting minutes that I know of nor on the ISO CPP mailing list. It is safe to say that something like a get_with_spins function is not in the pipeline.

To answer for libstdc++ (and libc++): They also do not spin. Aside from the TODO which came from the original patch, it does not look like there is any plan to change this. I've searched the GCC mailing list for mentions of changing this behavior, but found none. Doing a pre-sleep spin can hurt in the general case (if none of the get()s have a value, you've wasted a lot of CPU cycles), so a change here could have negative impacts.

To summarize: Implementations do not appear to spin now and there appear to be no plans to change the behavior in the near future, but that can change at any moment.

like image 97
Travis Gockel Avatar answered Oct 22 '22 23:10

Travis Gockel