为何std::this_thread::yield()比std::this_thread::sleep_for(0s)慢10倍?
为什么std::this_thread::yield()比std::this_thread::sleep_for(0s)慢10倍?
我测试了两个C++小程序:
第一个程序代码
#include <thread> int main() { for (int i = 0; i < 10000000; i++) { std::this_thread::yield(); } return 0; }
第二个程序代码
#include <thread> #include <chrono> int main() { using namespace std::literals; for (int i = 0; i < 10000000; i++) { std::this_thread::sleep_for(0s); } return 0; }
在我的系统(Ubuntu 22.04 LTS,内核版本5.19.0-43-generic)上运行,得到的计时结果分别为:
yield()版本
./a.out 0,33s user 1,36s system 99% cpu 1,687 total
sleep_for(0s)版本
./a.out 0,14s user 0,00s system 99% cpu 0,148 total
为什么std::this_thread::yield()比std::this_thread::sleep_for(0s)慢10倍?
注:g和clang的计时结果相似。
原因解析
这本质是STL实现层面的优化差异,背后对应Linux内核不同操作的开销区别:
std::this_thread::yield()通常直接调用内核的sched_yield()系统调用,这个操作会主动让当前线程放弃CPU,触发调度器重新选择线程运行,涉及完整的上下文切换与调度决策,单次调用开销约50微秒。- 而
std::this_thread::sleep_for(0s)在GCC/Clang的libstdc++/libc++实现中,会被直接优化为无系统调用的空操作——因为传入的睡眠时间为0,STL实现会跳过内核交互流程,单次操作开销仅约150纳秒,比sched_yield()快了近300倍。
循环1000万次的场景下,单次操作的开销差距被放大,最终呈现出总耗时10倍左右的差异。
内容的提问来源于stack exchange,提问作者matovitch
相关产品推荐
相关产品推荐

