Сравнение часов `std :: chrono` с` boost :: xtime` - PullRequest
0 голосов
/ 14 февраля 2019

Как C ++ 11 std::chrono часы steady_clock и high_resolution_clock сравниваются с boost::xtime::xtime_get() с точки зрения причуд и общих свойств на различных платформах?

Стандарт не гарантирует, что high_resolution_clock быть устойчивым (в нем явно упоминается, что это может быть псевдоним system_clock), так что это одна ловушка, на которую стоит обратить внимание.Другие свойства, которые приходят мне в голову:

  • Разрешение : стандарт C ++ 11 не гарантирует какого-либо разрешения;Каковы "реальные" разрешения этих часов?Как действует boost::xtime_get() в тех же системах?

  • Максимальная продолжительность : я знаю, что, например, clock() выходит из строя примерно через час в системах с 32-бит clock_t и номинальное разрешение 1 МГц.(Да, я знаю, что clock() должен выполнять несколько иную работу.) Могут ли стандартные часы C ++ 11 справляться с длительностью порядка дней, может быть, даже недель на всех известных платформах?

  • Любые другие известные проблемы или удивительные причуды (Редактировать: либо std::chrono часы или boost::xtime::xtime_get) ?

Ответы [ 2 ]

0 голосов
/ 15 февраля 2019

Несколько результатов от 1-го и 2-го рук, проверяющих поведение sleep_for с длительностью 1 миллисекунда:

Следующие платформы имеют тенденцию к "просыпанию", по крайней мере, в среднем (по времени более 1000 итераций)):

  • Подсистема Windows для Linux / g ++ (1,8 мс, очевидно, накладные расходы)
  • Подлинная Ubuntu / g ++ (1,1 мс)
  • FreeBSD / clang (1,1 мс)
  • Wingwin / g ++ (16 мс, очевидно, минимум)
  • Модель потоков OS X (Дарвин) / g ++ / POSIX (1,2 мс)

Пока что,ни одна платформа в среднем не "спит".

0 голосов
/ 14 февраля 2019

Как в C ++ 11 std :: chrono Clocks устойчивые и высокие_разрешения сравниваются с boost :: xtime :: xtime_get () с точки зрения причуд и общих свойств на различных платформах?

Любая библиотека синхронизации может предоставить только то, что может обеспечить базовая комбинация ОС / оборудования - полная остановка.

Даже если API библиотеки обещает разрешение наносекунд, это не означает, что базовая ОС / оборудование может обеспечитьэта точность.Таким образом, в конечном счете, API синхронизации не может улучшить качество платформы.

boost::xtime - это то, что было стандартизировано C (и впоследствии C ++) как timespec.Это пара {second, nanosecond}, которая используется как точка во времени и как длительность, в зависимости от функции, с которой она используется в стандартных заголовках C.Хотя при быстром обзоре заголовков наддува, похоже, используется xtime только как момент времени (я мог что-то пропустить).

timespec имеет долгую историю существующего использования, особенно в системах POSIX.Он существует в системах POSIX намного дольше, чем std::chrono, который был разработан в 2008 году и стандартизирован в C ++ 11 (2011).

Диапазон timespec (xtime) составляеткак правило, больше, чем возраст вселенной.Хотя в системах, которые не могут обеспечить 64-битный интегральный тип, диапазон timespec будет значительно меньше: +/- 68 лет, как правило, примерно в 1970 году, когда он используется в качестве временной точки.

КакКак упоминалось выше, timespec объявляет наносекундную точность на всех платформах, но обеспечивает только ту точность, которую может обеспечить базовая платформа.

chrono поставляет отдельные типы для временных точек и продолжительности.Это помогает отлавливать ошибки во время компиляции.Например, если вы добавляете два момента времени вместе, он не компилируется.9 утра сегодня + 7 утра сегодня бессмысленно.Однако, если вы вычли две временные точки, это имеет смысл и возвращает отдельный тип: длительность.9:00 сегодня - 7:00 сегодня 2 часа.

chrono предоставляет несколько типов для продолжительности и времени, которые могут отличаться как по точности, так и по представлению.«Встроенные» длительности - это наносекунды, микросекунды, миллисекунды, секунды, минуты и часы, каждый из которых представлен целочисленным типом со знаком (этот список расширен в проекте спецификации C ++ 2a).Но вы можете создавать свои собственные типы продолжительности с вашей собственной точностью и представлением (например, с плавающей точкой или библиотекой safe-int).

Разработчик chrono для любой конкретной платформы может рекламировать точность платформ.Функция "now()".Т.е. это не всегда должны быть наносекунды, это могут быть микросекунды или какие-то другие единицы.Продавец не обязан быть честным, но обычно это так.Клиенты могут запрашивать тип возвращаемого значения now() для его точности программным способом во время компиляции (в конце концов, это C ++).

Структуры данных chrono равны {count of units}, в отличие от xtime {seconds, nanoseconds} структура данных.Для chrono это верно как для длительностей, так и для временных точек, даже если это разные типы.

Макет {count of units} имеет несколько преимуществ по сравнению с макетом {seconds, nanoseconds}:

  • Есть возможность иметь меньший sizeof.system_clock::time_point обычно составляет 64 бита, а xtime обычно 128 бит.Это дает xtime превосходный диапазон.Однако библиотека chrono может также использоваться со 128-битными целочисленными типами, которые впоследствии будут иметь больший диапазон, чем xtime.

  • Клиенты могут сделать компромисс размера / диапазона сchrono.xtime клиенты получают то, что получают.

  • Арифметика быстрее / эффективнее и проще для программирования со структурой данных {count}, чем с {seconds, nanoseconds}.Это приводит к тому, что код становится меньше, быстрее и, как правило, более свободен от ошибок (отрицательные значения, обозначенные {seconds, nanoseconds}, представляют собой ужасающую историю).

  • Для данной sizeof и точности всегда можно получить больший диапазон со структурой данных {count}, чем в многопольной структуре данных, такой как {seconds, nanoseconds}.

Стандарт не гарантирует, что high_resolution_clock будет устойчивым (он явно упоминает, что это может быть псевдоним system_clock), так что это одна ловушка, на которую нужно обратить внимание.

На практике high_resolution_clock всегда является псевдонимом типа для steady_clock или system_clock.Который, зависит от платформы.Я советую просто использовать steady_clock или system_clock, чтобы вы знали, с чем имеете дело.

Разрешение: Стандарт C ++ 11 не гарантирует какого-либо разрешения;каковы "реальные" разрешения этих часов?

объявленных разрешений:

libc++/llvm:

system_clock
    rep is long long : 64 bits
    period is 1/1,000,000
    is_steady is 0

high_resolution_clock
    rep is long long : 64 bits
    period is 1/1,000,000,000
    is_steady is 1

steady_clock
    rep is long long : 64 bits
    period is 1/1,000,000,000
    is_steady is 1

high_resolution_clock is the same type as steady_clock

libstdc++/gcc:

system_clock
    rep is long : 64 bits
    period is 1/1,000,000,000
    is_steady is 0

high_resolution_clock
    rep is long : 64 bits
    period is 1/1,000,000,000
    is_steady is 0

steady_clock
    rep is long : 64 bits
    period is 1/1,000,000,000
    is_steady is 1

high_resolution_clock is the same type as system_clock

VS-2013:

system_clock
    rep is __int64 : 64 bits
    period is 1/10,000,000
    is_steady is 0

high_resolution_clock
    rep is __int64 : 64 bits
    period is 1/1,000,000,000
    is_steady is 1

steady_clock
    rep is __int64 : 64 bits
    period is 1/1,000,000,000
    is_steady is 1

high_resolution_clock is the same type as steady_clock

Из-за моих вступительных замечаний "«реальные» разрешения с большой вероятностью будут идентичны xtime для любой данной платформы.

Могут ли стандартные часы C ++ 11 справляться с длительностями в порядке дней, может быть, даженедели на всех известных платформах?

Да.Даже месяцы и годы.

Первое ограничение длительности, с которым вы столкнетесь, - это разрешение наносекундного разрешения.chrono гарантирует, что это будет иметь как минимум 64-битное целое представление со знаком, дающее вам диапазон + -292 года.Если говорить о system_clock, этот диапазон будет центрирован по 1970 году.

Любые другие известные проблемы или неожиданные причуды

При работе в или вблизи пределов диапазона, *Библиотека 1124 * может легко и тихо переполняться.Например, если вы сравните microseconds::max() с nanoseconds::max(), вы получите переполнение и получите неопределенный результат.Это происходит потому, что оператор сравнения сначала преобразует microseconds в nanoseconds перед выполнением сравнения, и это преобразование переполняется.

Держитесь подальше от ограничений продолжительности и диапазона time_point.Если вам приходится иметь дело с ними, и вы не знаете, как, ищите ответы в Stackoverflow.Задайте интересующий вас вопрос, если этот поиск не является удовлетворительным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...