Единицы измерения времени: меры и особенности исчисления
Единицы измерения времени: Freepick
Какие единицы измерения времени использовали наши предки? Почему минута состоит из 60 секунд, а час — из 60 минут? С детских лет нам приходится наблюдать за часами и выстраивать жизнь, глядя на их циферблат. Разберемся, как измеряют время и какие единицы при этом применяют.
В чем измеряется время
В современном мире человек не мыслит жизнь без времени. Мы то и дело поглядываем на часы, ориентируемся на расписание, договариваемся о встречах в определенный момент дня. Все это возможно благодаря тому, что создана единая система подсчета и определения временных интервалов.
В чем измеряется время? Как и для всех других величин, для него существуют определенные меры. В течение истории человечества они менялись и пересматривались. Сегодня актуальны следующие меры времени:
Какая единица времени является основной в СИ (наиболее широко используемая система единиц в мире)? На международном уровне за основу взяли секунду. Как же определяют ее длительность и что может послужить в этом случае эталоном?
Ранее в качестве образца для этого измерения использовали периоды вращения Земли вокруг своей оси или Солнца, рассчитывали вращение Луны вокруг Земли.
Сейчас Международная система единиц одну секунду определяет как временной интервал, который соответствует 9192631779 периодам излучения. За это время осуществляется переход с одного на другой сверхтонкий уровень основного состояния атома цезия (133) при температуре 273 К. Это так называемая атомная секунда.
Гораздо проще для восприятия представить одну секунду как сокращение человеческого сердца. Но, так или иначе, мы понимаем, что измерение времени начинается с приблизительного определения секунды, на котором дальше строятся все остальные расчеты.
Сведения о том, как перевести сутки в секунды и соотнести другие единицы времени, представлены в таблице:
Единицы времени: NUR.KZ
Отметим, что только для секунд, согласно системе СИ, применяются дольные и кратные единицы (приставки). Наука использует:
Таким образом, есть система основных единиц измерения времени. По ним легко ориентироваться, а это знание, безусловно, важно для каждого человека.
Единицы измерения времени: особенности
С исторической точки зрения первой единицей временных измерений были сутки. Эти небольшие промежутки времени люди отсчитывали, учитывая то, как вставало и садилось Солнце. Позже сутки были поделены на меньшие интервалы: часы, минуты, секунды.
Почему возникло именно такое деление? Ученые, отвечая на этот вопрос, опираются на двенадцатеричную систему исчисления древнего Шумера:
Несмотря на то что в мире в целом широко распространена десятеричная система исчисления, такое деление времени закрепилось в традиции и сохранилось. Кроме того, единицы измерения получили свои сокращения, которые сегодня являются общепринятыми:
С часами, минутами и секундами достаточно просто ориентироваться во временных координатах суток. Что касается последних, то в мире сохранилось две системы определения:
Чтобы обозначить более длинные временные интервалы, пользуются неделями, месяцами, годами, веками, тысячелетиями. Неделю, месяцы и годы составляют из целых количеств солнечных суток. Годы складывают в века и тысячелетия, а век часто делят на десятилетия:
Кроме того, в литературе можно встретить кратные году единицы под названием мегагод (Myr), то есть миллион лет, и гигагод (Gyr) — миллиард лет. Данные единицы использует космология, геология и науки, которые изучают историю нашей планеты и Вселенной. К примеру, для обозначения возраста последней применяют значение 13,72 ± 0,12 гигалет.
Все указанные единицы для измерения времени (за исключением секунды) внесистемные, то есть не употребляются международной системой СИ. Но это не делает их менее полезными в повседневной жизни.
Мы используем единицы измерения времени ежедневно и ежечасно. Человечество так привыкло к устоявшимся обозначениям, что мало кто задумывается об их происхождении или о том, как исчисляли время наши предки. Так или иначе, этот ценный ресурс не стоит оставлять без учета.
Узнавайте обо всем первыми
Подпишитесь и узнавайте о свежих новостях Казахстана, фото, видео и других эксклюзивах.
Точное время: измеряем, применяем
Цель данной статьи – изложить, полученный в ходе работы над проблемой материал о способах максимально точного измерения времени и использования на практике этих способов, а также рассмотреть варианты управления чем-либо программным с максимально достижимой точностью.
Статья рассчитана на читателей, уже имеющих некоторый опыт в программировании, и заметивших проблему точности выдержки временных интервалов стандартных функций. Автор статьи, begin_end, советует её читателям, программирующим на языке Delphi, так как все способы реализуются именно на этом языке.
Наша задача – найти лучший метод точного измерения малых временных интервалов (желаемая точность – 10^-6 секунды), определить наиболее эффективный способ программирования задержек в исполнении кода, с такой же точностью.
Программист, который уже пробовал разрабатывать различные прикладные приложения, например, связанные с передачей данных или с генерацией/анализом сигналов мог заметить, что все стандартные функции (sleep, beep, GetTickCount, таймеры) обладают большой погрешностью при работе с малыми значениями временного интервала. Это определено разрешением системного таймера, значение которого для разных компьютеров может несколько различаться. Узнать это разрешение можно, используя функцию GetSystemTimeAdjustment:
BOOL GetSystemTimeAdjustment(
PDWORD lpTimeAdjustment, // size, in 100-nanosecond units, of a periodic time adjustment
PDWORD lpTimeIncrement, // time, in 100-nanosecond units, between periodic time adjustments
PBOOL lpTimeAdjustmentDisabled // whether periodic time adjustment is disabled or enabled
);
Разберем эту функцию для использования в Delphi. В lpTimeIncrement записывается значение разрешения системного таймера в единицах по 100 наносекунд. Нам нужно получить это значение, и вывести его, к примеру, в миллисекундах. Получится такая программка (см. пример 1):
uses
SysUtils, windows;
var a,b:DWORD; c:bool;
begin
GetSystemTimeAdjustment(a,b,c);
WriteLn(‘System time adjustment: ‘+FloatToStr(b / 10000)+’ ms.’);
WriteLn;
Writeln(‘Press any key for an exit. ‘);
Readln;
end.
Результат исполнения выводится на экран, у меня значение таймера оказалось равным 10,0144 миллисекунд.
Что реально означает эта величина? То, что временные интервалы функций будут практически всегда кратны этой величине. Если это 10,0144 мс, то функция sleep(1000) вызовет задержку в 1001,44 мс. При вызове же sleep(5) задержка будет примерно 10 мс. Стандартный таймер Delphi, объект TTimer, естественно подвержен погрешности, но в еще большей степени. Объект TTimer основан на обычном таймере Windows, и посылает окну сообщения WM_TIMER, которые не являются асинхронными. Эти сообщения ставятся в обычную очередь сообщений приложения и обрабатываются, как и все остальные. Кроме того, WM_TIMER обладает самым низким приоритетом (исключая WM_PAINT), по отношению к другим сообщениям. GetMessage отправляет на обработку сообщение WM_TIMER лишь тогда, когда приоритетных сообщений в очереди больше не остается – сообщения WM_TIMER могут задерживаться на значительное время. Если время задержки превышает интервал, то сообщения объединяются вместе, таким образом, происходит еще и их утрата [1].
Для того чтобы хоть как то производить замеры для сравнительного анализа функций задержки, необходим инструмент, позволяющий точно измерять временные интервалы выполнения некоторого участка кода. GetTickCount не подойдет ввиду вышеописанного. Но автор узнал об возможности опираться на частоту тактов процессора, за некоторый интервал времени. Начиная с Pentium III, процессоры обычно содержат достаточно доступный программистам счетчик меток реального времени, Time Stamp Counter, TSC, представляющий собой регистр на 64 разряда, содержимое которого с каждым тактом процессора инкрементируется [2]. Счет в счетчике начинается с нуля каждый раз при старте (или аппаратном сбросе) ЭВМ. Получить значение счетчика в Delphi можно следующим образом (см. пример 2):
uses
SysUtils, windows;
begin
repeat WriteLn(FloatToStr(tsc)) until false;
end.
Здесь ассемблерная вставка помещает результат счетчика в регистры edx и eax, значение которых затем переносится в ts, откуда доступно как ts.count типа Int64. Приведенная программа непрерывно выводит в консоль значения счетчика. На некоторых версиях Delphi есть готовая команда rdtsc (read time stamp counter), позволяющая сразу получить значение счетчика функцией RDTSC [3] вот так:
function RDTSC: Int64; register;
asm
rdtsc
end;
Предположим, у нас есть значение счетчика, но как использовать его? Очень просто. Опираясь на то, что значение изменяется с постоянной частотой можно вычислять разницу в количестве тактов процессора после исследуемой команды и до нее:
В b будет число тактов процессора, прошедшее за время исполнения Command. Но тут есть один момент. Вызов tsc, дающий нам число тактов сам должен тоже затрачивать на это какое то количество тактов. И, для верности результата, его нужно вносить, как поправку, вычитаемую из полученного количества тактов:
Все бы ничего, но экспериментально получается, что иногда значения нашей поправки C различаются. Причина этого была найдена. Дело тут в особенности функционирования процессора, точнее его конвейера. Продвижение машинных инструкций по конвейеру связано с рядом принципиальных трудностей, в случае каждой из них конвейер простаивает. Время выполнения инструкции в самом лучшем случае определяется пропускной способностью конвейера. Промежуток времени, которому можно гарантированно верить, получая такты процессора – от 50 тактов [2]. Получается, что в случае определения поправки, самым точным значением будет минимальная величина. Экспериментально достаточно производить вызов функции поправки до 10 раз:
function calibrate_runtime:Int64;
var i:byte; tstsc,tetsc,crtm:Int64;
begin
tstsc:=tsc;
crtm:=tsc-tstsc;
for i:=0 to 9 do
begin
tstsc:=tsc;
crtm:=tsc-tstsc;
if tetsc
Теперь, когда у нас есть необходимый инструмент, поэкспериментируем с функциями задержки. Начнем со всем известной и всеми применяемой sleep:
procedure Sleep(milliseconds: Cardinal); stdcall;
Чтобы провести проверку точности задержки, включим в нашу консольную программу, кроме кода tsc и кода calibrate_runtime следующий код:
function cycleperms(pau_dur:cardinal):Int64;
var tstsc,tetsc:Int64;
begin
tstsc:=tsc;
sleep(pau_dur);
tetsc:=tsc-tstsc;
cycleperms:=(tetsc-calibrate_runtime) div pau_dur;
end;
Этот код мы вызовем из программы, задавая по нескольку раз разные значения pau_dur (паузы).Если вы обратили внимание, число тактов за время паузы затем делится на значение паузы. Так мы узнаем точность задержки в зависимости от ее времени. Для удобства проведения теста и вывода на экран/сохранения результата теста применен такой код (см. пример 3):
В нем мы исполняем cycleperms по пять раз для каждого временного интервала (от 1 до 10000 миллисекунд), а также считаем среднее значение. Получается таблица. Итак, полученные числа тактов процессора в ходе такого исследования:
Картину мы наблюдаем не самую лучшую. Поскольку частота процессора примерно 1778,8 МГц (см. пример 4), то значения тактов за 1 миллисекунду должны стремиться к приблизительному числу 1778800. Точность функции sleep не дает нам этого ни за 1, 10, 100 или 1000 миллисекунд. Только за десятисекундный промежуток времени значения близки. Пожалуй, если бы в тесте 4 не было 1781146, то усредненная величина была бы приемлемой.
Что можно сделать? Оставить функцию и рассмотреть что-то еще? Пока не стоит торопиться. Я узнал, что можно вручную задавать погрешность отсчета эталонного интервала времени, используя функцию timeBeginPeriod [2]:
MMRESULT timeBeginPeriod(
UINT uPeriod
);
Для поддержания такого высокоточного разрешения используются дополнительные системные ресурсы, поэтому нужно вызывать timeEndPeriod для их высвобождения по завершению всех операций. Код функции cycleperms для исследования такого sleep (см. пример 5):
function cycleperms(pau_dur:cardinal):Int64;
var tstsc,tetsc:Int64;
begin
timeBeginPeriod(1);
sleep(10);
tstsc:=tsc;
sleep(pau_dur);
tetsc:=tsc-tstsc;
timeEndPeriod(1);
cycleperms:=(tetsc-calibrate_runtime) div pau_dur;
end;
Еще есть малообъяснимая особенность, timeBeginPeriod(1), устанавливающая разрешение в 1 миллисекунду начинает давать эффект не сразу, а только после вызова sleep, поэтому в код, после timeBeginPeriod вставлено sleep(10). Результаты этого исследования:
Наблюдаемые данные гораздо лучше. Среднее значение за 10 секунд довольно точно. Среднее за 1 миллисекунду отличается от него всего на 1,7 %. Соответственно отличия за 10 мс составляет 0,056 %, за 100 мс – 0,33 % (странно вышло), за 1000 мс – 0,01 %. Меньший, чем 1 мс интервал, невозможно использовать в sleep. Но можно твердо сказать, что sleep годна для пауз в 1 мс при условии выполнения timeBeginPeriod(1), и точность sleep только растет с ростом задаваемого временного промежутка (см. пример 6).
Функция sleep основана на Native API функции NtDelayExecution, которая имеет следующий вид [5]:
NtDelayExecution(
IN BOOLEAN Alertable,
IN PLARGE_INTEGER DelayInterval );
Попробуем провести тест ее задержек, подобно sleep, но учитывать будет она даже микросекунды:
function cyclepermks(pau_dur:Int64):Int64;
var tstsc,tetsc,p:Int64;
begin
p:=-10*pau_dur;
tstsc:=tsc;
NtDelayExecution(false,@p);
tetsc:=tsc-tstsc;
cyclepermks:=(tetsc-calibrate_runtime) *1000 div pau_dur;
end;
Эта функция не прописана в windows.pas или ином другом файле, потому вызовем ее, добавив строку:
procedure NtDelayExecution(Alertable:boolean;Interval:PInt64); stdcall; external ‘ntdll.dll’;
Код, в котором мы вызываем функцию и строим таблицу результатов, следует подкорректировать вот так (см. пример 7):
После проведения исследования задержек, создаваемых NtDelayExecution получились интересные результаты:
Видно, что применять такую точность этой функции бесполезно на промежутках менее 1 миллисекунды. Прочие интервалы задержек несколько лучше, чем у sleep без измененного разрешения, но хуже, чем с высоким разрешением sleep (в принципе это понятно, ведь тут мы не создавали потоков с повышенным приоритетом, и вообще не делали ничего для повышения точности, подобно тому, как это делает timeBeginPeriod). А если добавить timeBeginPeriod? Посмотрим, что получится:
На микросекундных интервалах ситуация все та же. А вот на интервалах, начиная с 1 миллисекунды отличие, относительно 10-секундного значения составляет 0,84 %, что лучше аналогичного использования sleep (1,7 %) – NtDelayExecution дает задержку точнее.
При поиске средств программирования задержек в исполнении кода был найден еще один вариант [4], вроде бы предоставляющий возможность указывать интервал в микросекундах. Это WaitableTimer. Работать с ним можно через функции CreateWaitableTimer, SetWaitableTimer, WaitForSingleObjectEx. Вид процедуры cyclepermks, куда мы добавили WaitableTimer:
function cyclepermks(pau_dur:Int64):Int64;
var tstsc,tetsc,p:Int64; tmr:cardinal;
begin
tmr:=CreateWaitableTimer(nil, false, nil);
p:=-10*pau_dur;
tstsc:=tsc;
SetWaitableTimer(tmr, p, 0, nil, nil, false);
WaitForSingleObjectEx(tmr, infinite, true);
CloseHandle(tmr);
tetsc:=tsc-tstsc;
cyclepermks:=(tetsc-calibrate_runtime2) *1000 div pau_dur;
end;
Особенность применения WaitableTimer требует от нас также модификации расчета поправки, получаемой в calibrate_runtime:
function calibrate_runtime2:Int64;
var i:byte; tstsc,tetsc,crtm, p:Int64; tmr:cardinal;
begin
tstsc:=tsc;
crtm:=tsc-tstsc;
for i:=0 to 9 do
begin
tmr:=CreateWaitableTimer(nil, false, nil);
p:=0;
tstsc:=tsc;
SetWaitableTimer(tmr, p, 0, nil, nil, false);
CloseHandle(tmr);
crtm:=tsc-tstsc;
if tetsc
Ведь SetWaitableTimer и CloseHandle тоже исполняются за период учитываемого нами количества тактов процессора. Сразу добавим в код cyclepermks вызов timeBeginPeriod, надеясь на помощь этой процедуры в приросте точности (см. пример 8). Таблица результатов:
Увы, и здесь мы не получили возможность устанавливать задержки для промежутков меньше миллисекундных. Разница значений 1 миллисекунды и 10 секунд равна 5%. В сравнении с предыдущими способами, это хуже.
Перед тем, как делать выводы, скажу немного о собственно самом измерении времени. В приведенных исследованиях основой сравнений было число тактов процессора и у каждого компьютера оно разное. Если понадобится привести его к единицам времени на основе секунд, то нужно сделать следующее: применяя 10-секундную задержку NtDelayExecution получить число тактов процессора за эти 10 секунд или узнать длительность одного такта (см. пример 9). Зная количество тактов процессора в единицу времени, можно спокойно преобразовывать меньшие значения числа тактов процессора в значения времени. Кроме этого рекомендуется установить приложению приоритет реального времени.
Заключение. В результате проведенной работы было установлено, что можно очень точно (даже до отрезка времени, исчисляемого 50 тактами процессора) замерять время на ЭВМ. Эта задача решена успешно. Что же касается возможности самостоятельно задавать точные задержки в исполняемом коде, то тут ситуация такова: лучший обнаруженный метод, позволяет сделать это с разрешением не большим, чем 1 миллисекунда, с погрешностью разрешения на интервале 1 мс порядка 0,84 %. Это функция NtDelayExecution с установкой разрешения процедурой timeBeginInterval. Недостаток функции, по сравнению с оказавшейся менее точной sleep это громоздкий вызов и нахождение в составе недостаточно документированного Native API. Использовать Native API не советуют по причине возможной несовместимости отдельных API в разных операционных системах семейства Windows. В общем, то, очевидное преимущество функции NtDelayExecution все-таки вынуждает сделать выбор в ее пользу.
Литература:
1. Руссинович М., Соломон Д. Внутреннее устройство Microsoft Windows. – СПб.: Питер, 2005. – 992 с.
2. Щупак Ю.А. Win32 API. Эффективная разработка приложений. – СПб.: Питер, 2007. – 572 с.
3. RDTSC – Wikipedia [http://ru.wikipedia.org/wiki/Rdtsc]
4. CreateWaitableTimer – MSDN [http://msdn.microsoft.com/en-us/library/ms682492(VS.85).aspx]
5. NtDelayExecution – RealCoding [http://forums.realcoding.net/lofiversion/index.php/t16146.html]
Статья была написана 13.11.2009, автор begin_end. Некоторые моменты, рассматриваемые в статье автор обсуждал со slesh’ем, которому выражается благодарность за такую помощь.
Время и его измерение
Крайне рекомендую к просмотру или прослушиванию видеоролик (ниже). Уверен, многого Вы не знаете :), некоторые студенты пятого курса, к примеру, не знают о причине смены времён года.
Что было до появления маятниковых часов?
Песочные часы
Песочные часы – это два полукруглых сосуда, соединенных тонкой перемычкой с отверстием внутри. Устройство расположено вертикально, закреплено в прочном корпусе. По внешнему виду напоминают «восьмерку».
Первые песочные часы появились более 1000 лет назад. Исторически не установлено кто именно их создал. Известно, что древнегреческий ученый Архимед предложил отмерять промежутки времени, пересыпая равномерно песок из одного непрозрачного стеклянного сосуда в другой.
Недостатки:
Можно было измерять малые промежутки времени от 15 до 30 минут.
Необходимо постоянное присутствие человека, который ведет подсчет временных интервалов и переворачивает часы, когда верхняя колба опустошается.
На точность измерения времени влияла форма колбы, наличие изъянов внутри стеклянной чаши, однородность откалиброванных песчинок.
Суточная погрешность песочных часов составляла 15 – 20 минут.
Огневые часы
Право первооткрывателей огневых часов принадлежит Древнему Востоку. Во время правления первого китайского императора 3000 лет назад уже существовали такие примитивные устройства.
Существуют раные варианты огневых часов:
Свечные
Фитильные
В процессе горения достигались специальные метки, отсчитывающие определённые периоды. К меткам прикрепляли шарики на тонких нитях. Огонь поочередно пережигал крепление элементов, а звон от падения отмерял время.
Лампадные
Недостатки огневых часов:
Невозможность повторного использования некоторых элементов часов.
Длительное изготовление «деталей», тщательная разметка шкалы отсчета «сгораемого» времени.
Эти необычные часы стали причиной возникновения выражения «время истекло», а их название в переводе с древнегреческого означает «крадущая воду». Клепсидра — это прибор для измерения времени, известный со времен Древнего Египта и используемый вплоть до XVII века.
Каков же был принцип действия этих часов? В Древнем Египте, Вавилоне и в Древней Греции вода по капельке вытекала из отверстия в сосуде. И количеством вылившейся воды измерялись временные промежутки. В Китае и Индии, напротив, жидкость постепенно набиралась в пустой полусферический сосуд. Существует поэма, героине которой нужно было замедлить отсчет времени и она бросила в чашу жемчужину, чтобы вода не текла так быстро.
Главный недостаток:
Неравномерность истечения жидкости.
Солнечные часы
Самым распространенным хронометрическим прибором были солнечные часы, основанные на кажущемся суточном, а иногда и годовом движении Солнца.
Недостаток:
Недостаток:
Маятниковые часы
Интересно, как был откыт закон о периоде колебания маятника.
В 1583 г., имея около двадцати лет от роду, Галилей находился в Пизе, где, следуя совету отца, изучал философию и медицину. Однажды, находясь в соборе этого города, он, со свойственной ему любознательностью и смекалкой, решил наблюдать за движением люстры, подвешенной к самому верху, — не окажется ли продолжительность ее размахов, как вдоль больших дуг, так и вдоль средних и малых, одинаковой; ибо ему казалось, что продолжительность прохождения большой дуги может сократиться за счет большей скорости, с которой, как он видел, движется люстра на более высоких и наклонных участках. И пока люстра размеренно двигалась, он сделал грубую прикидку — его обычное выражение — того, как происходит движение взад и вперед, с помощью биения собственного пульса, а также темпа музыки, в которой он тогда уже был искушен с немалою от того для себя пользой.
И ему на основании таких подсчетов показалось, что он не заблуждается, подсчитав, что времена одинаковы, но не удовлетворенный этим, вернувшись домой, он, чтобы надежнее в этом удостовериться, решил сделать следующее.
Сверх того он сделал два сходных маятника, только достаточно разной длины. Он наблюдал, что, пока малый маятник делал какое-то число колебаний, например 300, по большим дугам, большой за то же время делал всегда одно и то же число колебаний, скажем 40, как по своим большим дугам, так и по совсем маленьким, и повторив это несколько раз, он заключил отсюда, что вполне одинакова продолжительность размахов одного и того же маятника, будут ли они весьма велики или весьма малы, и что почти нет при этом заметных различий, каковые надо приписать помехе со стороны воздуха, который больше противится быстрее движущемуся тяжелому телу, чем медленнее движущемуся.
Он видел также, что ни различие в абсолютном весе, ни разный удельный вес шаров не вызывали заметного изменения — все шары, лишь бы они были на нитях равной длины от их центров до точек подвеса, сохраняли достаточно постоянно равенство (времени) прохождения по всяким дугам; лишь бы не был взят легчайший материал, движению которого в воздухе легче препятствовать, так что оно быстрее сводится к покою.
При фиксированной длине период колебаний маятника не зависит от их амплитуды.
Поучительно, как Галилей следил за временем: при помощи музыки и пульса (кажется, на этот способ первым указал Кардано). Нам, людям XX века, привыкшим к ручным часам, не следует забывать об этих трудностях.
Достаточно точные часы были сконструированы как раз на основе открытого Галилеем свойства маятника. Кстати, в своих лабораторных экспериментах Галилей пользовался для измерения времени одним из вариантов водяных часов.
Упругий маятник позволил уменьшить конструкцию часов сразу до наручных.
Приинцип маятника лёг в основу создания одних из самых точных приборов по измерению времени.
Точный хронометр позволил правильно определять долготы, поэтому в отличие от карты 1492 года
. карты наконец стали похожи на тепершние.
Кварцевый механизм
С середины 20 века был изобретён кварцевый механизм электронных часов.
Теперь такие часы есть везде, как от платы на компьютере, так и в любом сотовом телефоне.
С появлением электронных часов было выяснено, что Земля вращается неравномерно, к примеру, на неё влияет даже одномоментный сброс листвы деревьев лиственных пород осенью!
С 1967 года время создают физики:
К чему такая точность?
Такая точность нужна, к примеру, для навигаторов GPS и Глонасс:


























