Почему `std::this_thread::yield()` в 10 раз медленнее, чем `std::this_thread::sleep_for(0s)`?

Просто тестирую две небольшие программы,

#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-универсальная),

./a.out  0,33s user 1,36s system 99% cpu 1,687 total

и:

./a.out  0,14s user 0,00s system 99% cpu 0,148 total

Почему std::this_thread::yield() в 10 раз медленнее, чем std::this_thread::sleep_for(0s)?

Н.Б. Время одинаково для g++ и clang++.

редактировать: как указано в ответе, это оптимизация реализации STL, вызов sleep(0) на самом деле в 300 раз медленнее (50 мкс против 150 нс).

Это деталь реализации, но sleep_for(x); обычно выполняет одну if (x>0) проверку, а затем ничего, если x равно нулю. В отличие от yield(), который, насколько я понимаю, фактически приостанавливает поток и возвращает управление ОС.

freakish 16.06.2023 00:13
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Быстро взглянем на источник для this_thread::sleep_for

template<typename _Rep, typename _Period>
inline void
sleep_for(const chrono::duration<_Rep, _Period>& __rtime)
{
    if (__rtime <= __rtime.zero())
      return;
    ...

Итак, sleep_for(0s) ничего не делает, на самом деле ваша тестовая программа использует 0,0 с системного времени, в основном пустой цикл, который полностью выполняется в пользовательском пространстве (на самом деле я подозреваю, что если вы скомпилируете с оптимизацией, он будет полностью удален)

С другой стороны, yield вызывает *sched_yield, который, в свою очередь, вызывает schedule() в пространстве ядра, таким образом, по крайней мере, выполняя некоторую логику, чтобы проверить, есть ли другой поток для планирования.

Я считаю, что ваши 0,33 секунды пользовательского пространства в основном накладные расходы на системные вызовы.

* Actually jumps to __libcpp_thread_yield which then calls sched_yield, at least on linux

Спасибо. Действительно, мы даже не выполняем системный вызов. К вашему сведению, кажется, что вызов sleep(0) из unistd.h намного медленнее.

matovitch 16.06.2023 00:24

Кроме того, после получения потока поток должен ждать, пока ОС снова не запланирует его для следующего запуска. Что также занимает (стенное) время

Pepijn Kramer 16.06.2023 07:32

Другие вопросы по теме