std::未来旋转等待吗

Does std::future spin-wait?

本文关键字:等待 未来 std 旋转      更新时间:2023-10-16

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

std::future上调用wait()get()会阻塞,直到通过异步操作(std::promisestd::packaged_taskstd::asyn函数)设置结果为止。结果的可用性通过共享状态进行通信,该状态基本上是一个原子变量:future等待promise(或async任务)将共享状态标记为就绪。这个等待和通知是通过futex系统调用在libstdc++中实现的。假设未来的未来只需要等待极短的时间(约为一微秒),那么在等待未来之前,在共享状态上旋转一小段时间,似乎可以获得性能提升。

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

// TODO Spin-wait first.

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

我将回答以下问题:std::future::get()是否执行旋转等待?

所有C++的答案是:它是一个实现细节。一个合格的标准库可能会旋转,也可能不会(同样,std::mutex::lock()也可以旋转)。是否会有一种机制来指定未来是否旋转以及如何旋转?值得关注的地方有std::experimental::future(即将推出标准库的完整版本)、boost::future(稍后可能成为标准的试验场)和hpx::future(具有高级future管理功能的性能库)。这些都没有明确规定纺纱的机制,我所知道的会议记录中也没有讨论过,ISO CPP邮件列表中也没有。可以肯定地说,类似get_with_spins函数的东西不在管道中。

回答libstdc++(和libc++):它们也不旋转。除了来自原始补丁的TODO之外,似乎没有任何计划来改变这一点。我在GCC邮件列表中搜索了关于改变这种行为的内容,但没有找到。在一般情况下,进行睡眠前旋转可能会造成伤害(如果get()都没有值,则浪费了大量CPU周期),因此此处的更改可能会产生负面影响。

总之:实现现在似乎没有旋转,在不久的将来似乎也没有改变行为的计划,但这种情况随时都可能改变。