std::future 旋转等待吗?

Does std::future spin-wait?

在更详细地解释这个问题之前,我会注意到答案显然取决于实现,所以我主要询问 libstdc++,但我也有兴趣了解 libc++。操作系统是 Linux.

std::future 上调用 wait()get() 会阻塞,直到结果由异步操作设置 - std::promisestd::packaged_task、或 std::asyn 函数。结果的可用性通过 共享状态 传达,它基本上是一个原子变量:未来等待共享状态被承诺(或异步任务)标记为就绪。这种等待和通知是通过 futex 系统调用在 libstdc++ 中实现的。假设 futex 是高性能的,在 future 期望只等待极短时间(大约几微秒)的情况下,似乎可以通过在共享状态上旋转短时间来提高性能在继续等待 futex 之前。

我在当前的实现中没有发现任何这种旋转的证据,但是,我确实在 atomic_futex.h at line 161 中找到了一条评论,我希望在其中找到这种旋转:

// TODO Spin-wait first.

所以我的问题是:是否真的有实施自旋等待的计划,如果有,持续时间将如何决定?此外,这是最终可以通过未来政策指定的功能类型吗?

我会回答这个问题:std::future::get() 执行 spin-wait 吗?

所有 C++ 的答案是:它是一个实现细节。符合标准的库可能会自旋,也可能不会(同样,std::mutex::lock() 被允许自旋)。将来是否会有一种机制来指定是否以及如何旋转?要查看的位置在 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 图书馆,具有用于 future 管理的高级设施)。 None 其中有明确指定旋转的机制,据我所知,在会议纪要中也没有讨论过,也没有在 ISO CPP 邮件列表中讨论过。可以肯定地说 get_with_spins 函数之类的东西不在管道中。

回答libstdc++(和libc++):它们也不旋转。除了来自 the original patch 的 TODO 之外,看起来没有任何更改它的计划。我在 GCC 邮件列表中搜索了有关更改此行为的提及,但发现 none。在一般情况下进行 pre-sleep 旋转可能会造成伤害(如果 get() 中的 none 有一个值,那么你已经浪费了很多 CPU 周期),所以此处更改可能会产生负面影响。

总而言之:实施现在似乎没有旋转,而且似乎没有计划在不久的将来改变行为,但随时可能改变。