Clock
Содержание:
EXAMPLES top
The example program below obtains the CPU-time clock ID of the
process whose ID is given on the command line, and then uses
clock_gettime(2) to obtain the time on that clock. An example run is
the following:
$ ./a.out 1 # Show CPU clock of init process
CPU-time clock for PID 1 is 2.213466748 seconds
Program source
#define _XOPEN_SOURCE 600
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
int
main(int argc, char *argv[])
{
clockid_t clockid;
struct timespec ts;
if (argc != 2) {
fprintf(stderr, "%s <process-ID>\n", argv);
exit(EXIT_FAILURE);
}
if (clock_getcpuclockid(atoi(argv), &clockid) != 0) {
perror("clock_getcpuclockid");
exit(EXIT_FAILURE);
}
if (clock_gettime(clockid, &ts) == -1) {
perror("clock_gettime");
exit(EXIT_FAILURE);
}
printf("CPU-time clock for PID %s is %ld.%09ld seconds\n",
argv, (long) ts.tv_sec, (long) ts.tv_nsec);
exit(EXIT_SUCCESS);
}
Несколько советов по выполнению таймирования
Между первым и вторым вызовами не должно быть:
1) Операций ввода-вывода. Если, конечно, вы не хотите протестировать быстродействие вашего винчестера или подсистемы консольного вывода.
2) Операций запроса данных у пользователя (например, с клавиатуры).
Может оказаться, что используемый в вашем компьютере процессор слишком быстр для таймирования небольшого фрагмента кода. В этом случае разность значений между вызовами будет равна 0.
Выход, как обычно, прост: заключить таймируемый фрагмент в цикл и крутить его там 1’000 или 1’000’000 раз. При этом накладывается дополнительное ограничение:
3) Таймируемый код не должен иметь побочных эффектов. Например, изменять значения переменных, внешних по отношению к этому фрагменту кода, или занимать память из кучи.
Если побочный эффект имеется, то перед следующей итерацией он должен быть каким-то образом скомпенсирован. Это, конечно, влияет на точность таймирования, но обычно незначительно. А если два сравниваемых алгоритма имеют одинаковые побочные эффекты, этой погрешностью вообще можно пренебречь.
Историческая справка по системам SMP
CLOCK_PROCESS_CPUTIME_IDCLOCK_THREAD_CPUTIME_IDподдельные результаты
Если процессоры в многопроцессорных системах используют разные источники
времени, то нет способа поддерживать сверку между регистрами таймера, так
как каждый ЦП будет работать со слегка отличающейся частотой. В этом случае
clock_getcpuclockid(0) вернёт ENOENT, чтобы указать на это
состояние. Двое часов в этом случае будут полезны, только если можно
убедиться, что процесс остался на определённом ЦП.
Процессоры в многопроцессорных системах не приступают к работе одновременно
и поэтому регистры таймера обычно работают со смещением. Некоторые
архитектуры содержат код, который пытается сократить это смещение при
загрузке системы. Однако код не может гарантировать точную подстройку
смещений. В glibc нет средств для работы с этими смещениями (в отличие от
ядра Linux). Обычно, эти смещения малы и поэтому, в большинстве случаев, их
влияние незначительно.
RemarksRemarks
Тип clock используется для получения текущего времени в формате UTC.A clock type is used to obtain the current time as UTC. Этот тип реализует экземпляр класса duration и шаблон класса time_point, а также определяет статическую функцию-член , которая возвращает время.The type embodies an instantiation of duration and the class template time_point, and defines a static member function that returns the time.
Часы считаются монотонными, если значение, возвращаемое при первом вызове , всегда не больше значений, возвращаемых при последующих вызовах .A clock is monotonic if the value that is returned by a first call to is always less than or equal to the value that is returned by a subsequent call to .
Часы считаются постоянными, если они монотонны и интервал времени между соседними тактами является постоянной величиной.A clock is steady if it is monotonic and if the time between clock ticks is constant.
Change an alarm
Cancel or delete alarm
- Open your phone’s Clock app .
- At the top, tap Alarm.
- On the alarm you want, tap the Down arrow .
- Cancel: To cancel an alarm scheduled to go off in the next 2 hours, tap Dismiss.
- Delete: To permanently delete the alarm, tap Delete.
Change alarm sound or song
Use a sound
- Open your phone’s Clock app .
- At the top, tap Alarm.
- On the alarm you want, tap the Down arrow .
- Tap the current sound’s name.
- Choose a sound:
- Pick a sound from the list: Tap it.
- Use your own sound file: If you’ve downloaded a sound file to your phone, tap Add new. Then tap your sound file. Learn where to find your files.
Use a song from YouTube Music, Pandora, or Spotify
- If you haven’t yet, download the YouTube Music, Pandora, or Spotify app. Learn how to download apps.
- Open the app and sign in to your account. Learn how to open apps.
- Open your phone’s Clock app .
- At the top, tap Alarm.
- On the alarm you want, tap the Down arrow .
- Tap the current sound’s name.
- Next to «Sounds,» tap YouTube Music, Pandora, or Spotify.
- Find a song you want to use, then tap it.
- YouTube: To choose a song or album, use a premium account. Free accounts don’t work with Clock.
- Pandora: To choose a song, use a premium account. Plus and free accounts can choose stations. Free accounts might hear ads. Note: Pandora alarms only work in the US.
- Spotify: To choose a song, use a premium account. Free accounts can choose playlists and might hear ads.
Change alarm name, repetition, or vibration
- Open your phone’s Clock app .
- At the top, tap Alarm.
- On the alarm you want, tap the Down arrow .
- Name: To name the alarm, tap Label.
- Repetition: To make the alarm repeat, tap Repeat and pick days of the week.
- Vibration: To turn alarm vibrations off or on, tap Vibrate.
Choose what Google Assistant does when you dismiss an alarm
- Make sure you have:
- Clock app by Google
- Google Search app
- Open your phone’s Clock app .
- At the top, tap Alarm.
- On the alarm you want, tap the Down arrow .
- Next to Google Assistant Routine, tap Add .
- Choose the actions you want the Assistant to do.
To change: Tap Settings .
To turn off an Assistant Routine: Next to the routine, tap Remove .
Unscheduling¶
An event scheduled with ,
, or with
and then triggered can be unscheduled in
multiple ways. E.g:
def my_callback(dt):
pass
# call my_callback every 0.5 seconds
event = Clock.schedule_interval(my_callback, 0.5)
# call my_callback in 5 seconds
event2 = Clock.schedule_once(my_callback, 5)
event_trig = Clock.create_trigger(my_callback, 5)
event_trig()
# unschedule using cancel
event.cancel()
# unschedule using Clock.unschedule
Clock.unschedule(event2)
# unschedule using Clock.unschedule with the callback
# NOT RECOMMENDED
Clock.unschedule(my_callback)
The best way to unschedule a callback is with .
is mainly an alias for that for that function.
However, if the original callback itself is passed to
, it’ll unschedule all instances of that
callback (provided is True, the default, other just the first match is
removed).
ОПИСАНИЕ
clock_getresclk_idresstruct timespecrestpclock_settimeresres
Функции clock_gettime() и clock_settime() получают и устанавливают
время указанных часов clk_id.
Аргументы res и tp представляют структуру timespec, определённую в
<time.h>:
struct timespec {
time_t tv_sec; /* секунды */
long tv_nsec; /* наносекунды */
};
Аргумент clk_id представляет идентификатор определённых часов, над
которыми производится действие. Часы могут использоваться системой в целом и
поэтому видимы всем процессам или конкретного процессу, если они отсчитывают
время только в пределах одного процесса.
Все реализации поддерживают системные часы реального времени, которые имеют
идентификатор CLOCK_REALTIME. Их время представляется в секундах и
наносекундах с начала Эпохи. Когда их время изменяется, на таймеры с
относительными интервалами это никак не влияет, но таймеры с абсолютной
точкой во времени учитывают это.
Может быть реализовано много часов. Представление соответствующих значений
времени и влияние на таймеры не определено.
В последних версиях glibc и ядра Linux поддерживаются следующие часы:
Что влияет на тайминг кода?
Тайминг кода является достаточно простым и прозрачным, но ваши результаты могут существенно отличаться из-за ряда вещей:
Во-первых, убедитесь, что вы используете режим конфигурации Release, а не Debug. Во время режима Debug оптимизация обычно отключена, а она может оказывать значительное влияние на результаты. Например, в конфигурации Debug, выполнение сортировки элементов массива через std::sort() на компьютере автора заняло секунды, что в 34 раза больше, нежели в конфигурации Release!
Во-вторых, на результаты тайминга влияют процессы, которые ваша система может выполнять в фоновом режиме. Для достижения наилучших результатов убедитесь, что ваша ОС не делает ничего, что интенсивно нагружает процессор, жесткий диск (например, запущен поиск файла или сканирование антивирусом) или расходует много памяти (например, вы играете в игры или работаете в фото или видео редакторе).
Выполняйте тайминг как минимум 3 раза. Если результаты одинаковые — выбираем среднее. Если один или два результата значительно отличаются друг от друга, то запустите тайминг еще несколько раз, пока не получите лучшее представление о том, какие из результатов оказались «левыми»
Обратите внимание, некоторые, казалось бы, невинные вещи, такие как веб-браузеры, могут временно увеличить нагрузку на ваш процессор до 100%, когда сайт, на котором вы находитесь в фоновом режиме, выполняет целую кучу скриптов JavaScript (рекламные баннеры, запуск видео, сложная анимация и т.д.). Запуск тайминга несколько раз позволит определить, повлияло ли подобное событие на ваши результаты
В-третьих, при сравнении двух фрагментов кода старайтесь не запускать ничего лишнего в фоновом режиме при пригонах кода, так как это также может повлиять на результаты тайминга. Возможно, ваш антивирус начал сканирование в фоновом режиме, или, может быть, вы решили послушать музыку в стриминговом сервисе (и это всё в перерывах между прогонами).
Рандомизация также может повлиять на тайминг. Если бы мы отсортировали массив, заполненный случайными числами, то это бы повлияло на результаты тайминга (тот факт, что числа являются рандомными). Рандомизацию использовать можно, но убедитесь, что ваше стартовое значение является фиксированным (т.е. не используйте системные часы в качестве стартового значения) и результаты рандомизации идентичны при каждом запуске. Кроме того, убедитесь, что в фрагментах кода не используется пользовательский ввод, так как время ожидания ввода от пользователя не должно учитываться при определении эффективности кода.
Наконец, ваши результаты действительны только для архитектуры вашего компьютера, ОС, компилятора и системных/технических характеристик. Вы можете получить совсем другие результаты на других системах, которые имеют другие сильные и слабые стороны.
ЭлементыMembers
Общедоступные определения типовPublic Typedefs
| ИмяName | Описание:Description |
|---|---|
| Синоним для .A synonym for . | |
| Синоним для типа, который используется для представления тактового периода при автономном создании экземпляра .A synonym for the type that is used to represent the tick period in the contained instantiation of . | |
| Синоним для типа, который используется для представления числа тактов часов при автономном создании экземпляра .A synonym for the type that is used to represent the number of clock ticks in the contained instantiation of . | |
| Синоним для , где является синонимом для самого типа часов или для другого типа часов, настроенного на ту же эпоху и имеющего тот же вложенный тип .A synonym for , where is a synonym for either the clock type itself or another clock type that is based on the same epoch and has the same nested type. |
Открытые методыPublic Methods
| nameName | Описание:Description |
|---|---|
| Статический.Static. Возвращает объект , наиболее точно соответствующий указанному времени.Returns a that most closely approximates a specified time. | |
| Статический.Static. Возвращает текущее время.Returns the current time. | |
| Статический.Static. Возвращает объект , наиболее точно соответствующий указанному объекту .Returns a object that most closely approximates a specified . |
Открытые константыPublic Constants
| ИмяName | Описание:Description |
|---|---|
| Указывает, являются ли часы монотонными.Specifies whether the clock type is monotonic. | |
| Указывает, являются ли часы постоянными.Specifies whether the clock type is steady. |
Разница в производительности между обычными и vDSO-системными вызовами
В этом эксперименте мы с помощью microbenchmark измерим, насколько быстрее выполняется через vDSO по сравнению обычным системным вызовом.
Для этого мы запустим в EC2-инстансе тестовую программу с тремя циклами. Сначала будем тестировать с clocksource, равным , а затем — .
Устанавливать clocksource равным в EC2 небезопасно. Маловероятно, но все же возможно, что это может привести непредвиденному отставанию часов (backwards clock drift). Не делайте этого в production-системах.
Условия эксперимента
Параметры AWS-инстанса:
- Amazon Linux AMI 2016.09.1 (HVM), SSD Volume Type (AMI: ami-f173cc91),
- m4.xlarge instance size,
- зона us-west-2c.
Время выполнения мы будем измерять с помощью программы . Вы можете удивиться: «как можно использовать программу , которая способна дестабилизировать источник информации о времени (clocksource)?»
К счастью, разработчик ядра Ingo Molnar написал программу для определения фактов искажения времени (time warps): time-warp-test.c. Прошу заметить, что для работы на 64bit x86-системах программа должна быть немного изменена.
Во время проведения нашего эксперимента утилита искажений времени не зафиксировала.
Для получения более обоснованного результата можно сделать следующее:
- Отставание часов (backward clock drift) маловероятно, но возможно. Многократное выполнение эксперимента и вероятностный анализ собранных данных может помочь отфильтровать некорректные значения.
- Эксперимент может быть повторен на невиртуализированных системах, которые не подвержены проблеме отставания или убегания часов (clock drift). Сначала можно протестировать работу через vDSO. Затем программа может быть изменена, чтобы .
Для целей нашего эксперимента было достаточно прогона тестов на искажения времени.
NOTE for SMP systems
The CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID clocks are realized on many platforms using timers from the CPUs (TSC on i386, AR.ITC
on Itanium). These registers may differ between CPUs and as a consequence these clocks may return bogus results if a process is migrated to another CPU.
If the CPUs in an SMP system have different clock sources then there is no way to maintain a correlation between the timer registers since each CPU will run
at a slightly different frequency. If that is the case then clock_getcpuclockid(0) will return ENOENT to signify this condition. The two clocks
will then only be useful if it can be ensured that a process stays on a certain CPU.
The processors in an SMP system do not start all at exactly the same time and therefore the timer registers are typically running at an offset. Some
architectures include code that attempts to limit these offsets on bootup. However, the code cannot guarantee to accurately tune the offsets. Glibc contains no
provisions to deal with these offsets (unlike the Linux Kernel). Typically these offsets are small and therefore the effects may be negligible in most
cases.
Шаблон программы
Если вы попали в такую ситуацию, то вот вам совет типа «хозяйке на заметку».
Эта «рыба» позволяет узнать время выполнения фрагмента кода.
Включение заголовка необходимо для вывода сообщений в стандартный вывод (т.е. на экран).
Включение заголовка дает возможность пользоваться функцией и сопутствующими типами и константами. Что нам собственно и нужно для таймирования.
Единственная функция, которую мы будем использовать для таймирования, имеет следующую сигнатуру:
Функция возвращает время, прошедшее с момента запуска процесса (т.е. собственно с момента запуска данного приложения) в тиках таймера. Тип возвращаемого значения — обычно является псевдонимом типа (определяется в ). Если функция не может получить системы время с начала процесса, функция возвращает значение -1, приведенное к типу . (С такой ошибкой я никогда не встречался, поэтому я буду опускать проверку возвращаемого значения на -1.)
Для перевода тиков таймера в секунды служит константа , также определенная в .
Алгоритм работы прозрачен: перед выполнением таймируемого кода засекаем время, после выполнения таймируемого кода еще раз засекаем время, их разность даст нам искомое время, за которое выполнялся код. Остается только перевести его из тиков в секунды.
В приведенном шаблоне программы хотелось бы обратить внимание именно на последний шаг. Поскольку — целочисленный тип, а — целочисленная константа, то для получения дробных частей секунд необходимо хотя бы одну из частей выражения привести к типу с плавающей точкой
Результаты
Из результатов видно, что обычные системные вызовы в условиях ec2 примерно на 77% медленнее vDSO-вызовов:
5 миллионов вызовов :
- vDSO включен:
- real: 0m0.123s
- user: 0m0.120s
- sys: 0m0.000s
- обычные системные вызовы:
- real: 0m0.547s
- user: 0m0.120s
- sys: 0m0.424s
50 миллионов вызовов :
- vDSO включен:
- real: 0m1.225s
- user: 0m1.224s
- sys: 0m0.000s
- обычные системные вызовы:
- real: 0m5.459s
- user: 0m1.316s
- sys: 0m4.140s
500 миллионов вызовов :
- vDSO включен:
- real: 0m12.247s
- user: 0m12.244s
- sys: 0m0.000s
- обычные системные вызовы:
- real: 0m54.606s
- user: 0m13.192s
- sys: 0m41.412s
Патчи для Xen на подходе
Чтобы исправить эту проблему, необходимо добавить поддержку vDSO в Xen. К счастью, в работе уже находится несколько соответствующих патчей.
Пока это (или аналогичное) изменение не попадет в ядро, а затем и в EC2, системные вызовы и будут выполняться на 77% медленнее, чем на аналогичных системах с поддержкой vDSO.
Triggered Events¶
New in version 1.0.5.
A triggered event is a way to defer a callback. It functions exactly like
schedule_once() and schedule_interval() except that it doesn’t immediately
schedule the callback. Instead, one schedules the callback using the
returned by it. This ensures that you can call the event
multiple times but it won’t be scheduled more than once. This is not the case
with :
# will run the callback twice before the next frame Clock.schedule_once(my_callback) Clock.schedule_once(my_callback) # will run the callback once before the next frame event = Clock.create_trigger(my_callback) event() event() # will also run the callback only once before the next frame event = Clock.schedule_once(my_callback) # now it's already scheduled event() # won't be scheduled again event()
In addition, it is more convenient to create and bind to
the triggered event than using in a function:
from kivy.clock import Clock
from kivy.uix.widget import Widget
class Sample(Widget):
def __init__(self, **kwargs):
self._trigger = Clock.create_trigger(self.cb)
super(Sample, self).__init__(**kwargs)
self.bind(x=self._trigger, y=self._trigger)
def cb(self, *largs):
pass
Even if x and y changes within one frame, the callback is only run once.
has a timeout parameter that
behaves exactly like .
Description
The function clock_getres() finds the resolution (precision) of the specified clock clk_id, and, if res is non-NULL, stores it in the
struct timespec pointed to by res. The resolution of clocks depends on the implementation and cannot be configured by a particular process. If the time
value pointed to by the argument tp of clock_settime() is not a multiple of res, then it is truncated to a multiple of res.
The functions clock_gettime() and clock_settime() retrieve and set the time of the specified clock clk_id.
The res and tp arguments are timespec structs, as specified in :
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
clk_id
All implementations support the system-wide realtime clock, which is identified by CLOCK_REALTIME. Its time represents seconds and nanoseconds since
the Epoch. When its time is changed, timers for a relative interval are unaffected, but timers for an absolute point in time are affected.
More clocks may be implemented. The interpretation of the corresponding time values and the effect on timers is unspecified.
Sufficiently recent versions of GNU libc and the Linux kernel support the following clocks:
- CLOCK_REALTIME
- System-wide realtime clock. Setting this clock requires appropriate privileges.
- CLOCK_MONOTONIC
- Clock that cannot be set and represents monotonic time since some unspecified starting point.
- CLOCK_PROCESS_CPUTIME_ID
- High-resolution per-process timer from the CPU.
- CLOCK_THREAD_CPUTIME_ID
- Thread-specific CPU-time clock.
Статьи по теме
Если вам понравилась эта статья, рекомендую прочитать и другие наши публикации, в которых также содержится много низкоуровневой технической информации:
- Micro-optimizations matter: preventing 20 million system calls
- How setting the TZ environment variable avoids thousands of system calls
- Monitoring and Tuning the Linux Networking Stack: Sending Data
- Monitoring and Tuning the Linux Networking Stack: Receiving Data
- Illustrated Guide to Monitoring and Tuning the Linux Networking Stack: Receiving Data
- The Definitive Guide to Linux System Calls
- work?
- work?
- APT Hash sum mismatch
- HOWTO: GPG sign and verify deb packages and APT repositories
- HOWTO: GPG sign and verify RPM packages and yum repositories
Ссылки:
- Оригинал: Two frequently used system calls are ~77% slower on AWS EC2.
Пожалуйста, помогите c переводом:
Policy – Forestry Commission England continues to
take the lead on grey squirrel policy on behalf of Defra.
Английский-Русский
1. Lol when @hartdenton develops his coachella polaroids
2. Usting @melton as my bitch for gueen
3. Trying to pack for LA
4. Fresh nails wha dis
5. Me once my motor cycle license is done this summer
6. So cute
7. The detail. . . even down to my snake rings. . . Amazing!
Английский-Русский
It slides comfortably into the ‘affordable’ bracket though, considering its supersized display, and when it lands on contract (which should be soon) it won’t carry hefty monthly fees.
Английский-Русский
Mendeleev was foreshadowed in his great generalization by De Chancourtois’s helix of elements of 1863, J.A.R. New-lands’s *law of octaves* (1864-5)-which uncovered periodicity in the 8th elements of his chemical groupings — and W. Odling’s work, which suggested that recurrent chemical properties in elements arranged according to atomic weight could not be accidental.
Английский-Русский
Schedule before frame¶
New in version 1.0.5.
Sometimes you need to schedule a callback BEFORE the next frame. Starting
from 1.0.5, you can use a timeout of -1:
Clock.schedule_once(my_callback, ) # call after the next frame Clock.schedule_once(my_callback, -1) # call before the next frame
The Clock will execute all the callbacks with a timeout of -1 before the
next frame even if you add a new callback with -1 from a running
callback. However, has an iteration limit for these
callbacks: it defaults to 10.
If you schedule a callback that schedules a callback that schedules a … etc
more than 10 times, it will leave the loop and send a warning to the console,
then continue after the next frame. This is implemented to prevent bugs from
hanging or crashing the application.
If you need to increase the limit, set the property:
Пример
В приведённом ниже примере сравниваются два алгоритма, выполняющие одну и ту же задачу: генерация квадратов чисел от 0 до 999 и поиск среди этих значений некоторого числа. В первом случае для хранения значений используется контейнер , во втором — контейнер . (Пример чисто демонстрационный. Понятно, что в реальной программе такие глупости ни кто писать не будет!)
Обратите внимание, что
-
таймируемый код слишком прост для моего процессора, поэтому для него используется цикл;
-
таймируемый код имеет побочный эффект, который компенсируется вызовом метода для контейнера.
Для результата вызова второй функции организована переменная, которая после таймирования выводится на экран. Сделано специально, что бы умный оптимизирующий компилятор, обнаружив, что результат вызова функции не используется, не соптимизировал и сам вызов функции к чертям собачьим.
Необходимая информация
Есть несколько важных аспектов, с которыми желательно ознакомиться, чтобы лучше понять описание проблемы и соответствующие фрагменты кода.
Системные вызовы Linux и vDSO
Прежде чем продолжать чтение этой статьи, настоятельно рекомендуем внимательно изучить нашу предыдущую публикацию, в которой детально описана работа системных вызовов Linux: The Definitive Guide to Linux System Calls (на английском языке).
vDSO по сути является предоставляемой ядром общей библиотекой, которая отображается в адресное пространство каждого процесса. Когда происходит вызов , , или , glibc пытается выполнить код, предоставляемый vDSO. Этот код получает необходимые данные без переключения в контекст ядра и таким образом помогает избежать дополнительных расходов на выполнение настоящего системного вызова.
Поскольку сделанные через vDSO системные вызовы не приводят к переключению в контекст ядра, не получает соответствующие уведомления. В результате в выводе не будет упоминания о, например, , если программа успешно сделала этот системный вызов через vDSO. Вместо в этом случае нужно использовать . Более подробную информацию о том, как устроена утилита , можно найти в нашей публикации «How does strace work».
В AWS EC2 появляется в выводе . Это происходит потому, что vDSO в некоторых ситуациях выполняет обычные системные вызовы.
Время в Linux
В работающих под управлением Linux системах с архитектурой x86 для получения информации о времени используется несколько различных механизмов:
- программируемый таймер прерываний (Programmable Interrupt Timer);
- часы реального времени (Real-Time Clock);
- таймер событий высокой точности (High Precision Event Timer);
- локальный таймер APIC (local APIC timer);
- счетчик временных меток (Time Stamp Counter).
У каждого из названных механизмов есть свои плюсы и минусы. Подробную информацию можно найти в исходниках ядра Documentation/virtual/kvm/timekeeping.txt.
Важно понимать, что виртуализация создает дополнительные трудности при работе с информацией о времени. Например:
- Выполняющиеся на одном хосте виртуальные машины используют единый источник информации о времени, при этом обновить эту информацию на всех гостевых машинах в один и тот же момент невозможно. Более того, на некоторых виртуальных машинах во время работы критически важных частей ядра прерывания вообще могут быть отключены.
- Некоторые из механизмов работы со временем (например, Time Stamp Counter) уже изначально виртуализированы. Чтение из регистра TSC может влиять на производительность, приводя к получению неточных данных и отставанию часов (backwards time drift).
- Миграция виртуальных машин между гипервизорами с разными CPU может оказаться проблематичной, если система работы со временем завязана на тактовую частоту процессора.
Парни из VMWare опубликовали очень интересную статью, в которой описаны эти и другие вопросы, связанные с работой со временем. Информация в этой статье представлена как специфичная для VMWare, но по большому счета она относится к любой системе виртуализации.
Для решения этих и других проблем в KVM и Xen имеются собственные системы работы со временем: KVM PVclock и Xen time. В ядре Linux они называются clocksource (источник информации о времени).
Текущий clocksource системы может быть найден в файле .
Именно к этому источнику обратится система при выполнении вызова или .