Быстрый кроссплатформенный таймер?

Я хочу улучшить сборщик мусора D, добавив некоторые эвристики, чтобы избежать запусков сборки мусора, которые вряд ли приведут к значительному освобождению. Одна эвристика, которую я хотел бы добавить, заключается в том, что GC не следует запускать более одного раза за X времени (возможно, один раз в секунду или около того). Для этого мне нужен таймер со следующими свойствами:

  1. Он должен быть в состоянии захватить правильное время с минимальными накладными расходами. Вызов core.stdc.time занимает время, примерно эквивалентное небольшому выделению памяти, так что это не лучший вариант.

  2. В идеале должен быть кроссплатформенным (как ОС, так и ЦП) для простоты обслуживания.

  3. Сверхвысокое разрешение не так уж важно. Если время точное, может быть, до 1/4 секунды, этого достаточно.

  4. Должен работать в многопоточном/многопроцессорном контексте. Инструкция x86 rdtsc не будет работать.

РЕДАКТИРОВАТЬ: простая старая функция C clock() кажется достаточно быстрой. Однако здесь переполнение является проблемой. В 32-битных Windows и Linux clock_t определяется как 32-битное целое число со знаком. Когда он переполняется, становится ли он отрицательным, или функция clock() использует дополнительную логику, чтобы заменить его на ноль? Если он обернут до нуля, то это поможет. Если он превращается в отрицательный (который также представляет коды ошибок и т. д.), то он не будет работать.

Изменить № 2: я все равно попробовал эвристику, используя clock() и игнорируя проблему переполнения, просто в качестве теста. Он работает настолько плохо, что не стоит дальнейшего изучения.


person dsimcha    schedule 21.02.2011    source источник


Ответы (2)


В идеале должен быть кроссплатформенным (как ОС, так и ЦП) для простоты обслуживания.

Я думаю, что это приводит вас к тому, что вы можете найти в стандартной библиотеке C.

Возможно, часы?

person Vladimir Panteleev    schedule 22.02.2011

Что ж, мое первое предложение — использовать core.time или std.datetime. У него есть StopWatch. Разве это не достаточно быстро? Он использует стандартные монотонные часы для системы, и я надеюсь, что это будет достаточно быстро. Это, безусловно, самая высокая точность, которую вы собираетесь получить (хотя как высокая точность влияет на скорость, я не знаю). Однако, если это недостаточно быстро, я вовсе не уверен, что другие ваши варианты лучше. Как правило, вы получаете либо вторую точность, либо высокую точность. Между ними не так много. И с высокой точностью, как правило, это точность не менее микросекунды, и вопрос в том, насколько она превышает это значение. Точность 1/4 секунды не совсем нормальная.

Предложение Cybershadow о часах может помочь - конечно, это ваш единственный вариант, который насколько мне известно, является стандартным C, но может быть достаточно быстрым, а может и нет.

Помимо часов... В Linux, если вам нужен немонотонный способ получить время с более высокой точностью, чем одна секунда, я считаю, что gettimeofday ваш единственный реальный вариант, но я не знаю, насколько это быстро. В Windows лучшим немонотонным решением, о котором я знаю, является getSystemTimeAsFiletime, но в Windows есть несколько функций времени, с которыми вы можете поиграться.

Вы можете посмотреть на Clock.currStdTime std.datetime, чтобы увидеть, как сделать любой из них (хотя он использует clock_gettime на Posix, если он доступен, что и использует core.time - хотя и с другими часами - так что вы, вероятно, хотите, чтобы часть else этого для Linux, если StopWatch слишком медленный для вас). Однако он преобразуется в hnsecs с полуночи 1 января 1 года нашей эры, поэтому в зависимости от того, что вы делаете с числом, вы можете пропустить эту часть расчета.

person Jonathan M Davis    schedule 22.02.2011
comment
Не хочу никого тревожить, но я читал несколько статей о проблемах с QueryPerformanceCounter в Windows (StopWatch использует его в своей реализации). Редактировать: я все время забываю нажимать Shift+Enter, и в итоге я публикую... Извините. Вот несколько статей: support.microsoft.com/kb/895980 virtualdub.org/blog/pivot/entry.php?id=106 jongampark.wordpress.com/2008/ 19/04/ - person Andrej Mitrović; 22.02.2011
comment
Я посмотрю на эти ссылки позже, но, насколько мне известно, QueryPerformanceCounter отлично подходит для тайминга. Он пытается использовать его для получения текущего времени, что является большой проблемой. Если вы попытаетесь сделать это, ваши результаты будут дрейфовать, что, очевидно, плохо. - person Jonathan M Davis; 22.02.2011