Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Второй выпуск рассылки, в котором я объясняю,


ЛИНУКСОИДЫ ПРОТИВ МАСДАЙНИКОВ!
 
Здравствуйте, Уважаемые Подписчики!
 
Сегодняшний выпуск будет посвящен различиям в реализации таймерных
функций Виндовс и Линукс. Потом как обычно, анонсы и ссылки на новые
 материалы. Проблемы со временем никак не заканчиваются, поэтому выпуски
 рассылки и обновлений на сайте пока остаются нерегулярными.
Однако думаю, что лучше выпускать нерегулярно, чем не выпускать вообще.
 
Итак для начала о таймерах:
Пришлось мне как-то недавно по долгу службы разбираться
с реализацией таймеров в винде и в линуксе. Я конечно был морально готов к тому,
что ни та ни другая ОС не являются системами реального времени, но чтобы
разница между точностью их таймеров составляла несколько порядков!!!
Этот факт настолько впечатлил меня, что я решил посвятить этому специальный
выпуск рассылки.
 
Вначале немного теории:
 
В практическом программировании иногда возникает необходимость заряжать
системные таймеры на короткие промежутки времени. Это бывает нужно,
например, в случаях обработки мультимедийного контента, при опросе быстрых
периферийных устройств и.т.д.

Если ядро микропроцессора работает на частоте, скажем 500 МГц, то очевидно, что
максимальная теоретическая частота прерываний, которую может выдать таймер,
будет 1/5*10^6, то есть порядка миллисекунды. Так как современные
компьютеры работают на частотах выше 1 ГГц, то соответственно даже с учетом
конвейерного способа обработки команд, эта частота всё-равно не может быть
меньше миллисекунды.
Так как WinNT не позволяет пользовательским программам получать прямой доступ к
векторам прерываний, то программист, желающий в этой ОС воспользоваться и
насладиться всей мощью современной процессорной архитектуры, вынужден или
извращаться с консольными приложениями, что не всегда применимо, или
пользоваться тем таймерным интерфейсом, который предоставляет ему система.
Вот теперь мы переходим к самому интересному.
 
Как это сделано в линуксе:
 
Существуют специальные структурки:
struct itimerval {
    struct timeval it_interval; /* следующее значение */
    struct timeval it_value;    /* текущее значение */
};
struct timeval {
    long tv_sec;                /* секунды */
    long tv_usec;               /* микросекунды */
};

Хочу обратить ваше внимание, что формат переменной tv_usec есть именно микросекунды.
Чтобы запустить таймер в линуксе, нужно заполнить эту структуру, затем вызвать
функцию setitimer с соответствующими параметрами.
 
#include <sys/time.h>
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);
 
Например, так:
 
itimerval newset,origset;
...
setitimer(ITIMER_REAL, &newset, &origset);
...
 
В этом случае (режим ITIMER_REAL) таймер загрузится значением из newset, старое значение
будет выгружено в origset. Таймер будет уменьшать своё значение до нуля, затем
вызовет обработчик сигнала переполнения таймера, потом перезагрузится и будет считать
дальше до следующего переполнения.
Всё просто и функционально. И интервал времени можно измерить до микросекунд.
На самом деле интервал отсчета может быть ещё меньше, если используется структура
timespec, которая отличается от timeval тем, что вместо микросекунд хранит наносекунды:
 
time_t tv_sec;  /* Секунды */
long   tv_nsec; /* Наносекунды */
 
См. описание стандарта POSIX, например здесь:
http://www.intuit.ru/department/se/pposix/12/pposix_12.html
Полное описание способов использования таймеров в Линуксе не входит в задачи этой статьи, интересующиеся могут найти подробности, например, на сайте опеннет-ру:
То есть, ОС Линукс предоставляет программистам максимально проработанный
и удобный интерфейс доступа к таймерам с очень широкими возможностями.
Теперь посмотрим, как это организовано в виндовс:
 
Таймеры в виндовс:
 
Поскольку эта система сделана для домохозяек, её и программировали
видимо домохозяйки :))
Поэтому и интерфейс тут очень простой, состоящий по сути
из одной API - функции:
 
_sleep(interval);
 
где interval есть величена, выраженная в МИЛЛИСЕКУНДАХ.
(да и то правда - зачем домохозяйкам могут понадобиться микросекунды? :))
Маньяки, которые хотят непременно под виндами заполучить промежутки
времени меньше миллисекунды вынуждены обращаться к системным вызовам, например
со следующим синтаксисом:
 
int Mytimer_mks()
{
LARGE_INTEGER a, b, f;
        __int64 c;
        QueryPerformanceFrequency(&f);
        QueryPerformanceCounter(&a);
        _sleep(0);
        QueryPerformanceCounter(&b);
        c = (__int64)(b.QuadPart - a.QuadPart)*1000000/(__int64)(f.QuadPart);
        printf("timer mcs is = %d\n", c);

return 0;
        }
 
В данном случае вызовы системной функции QueryPerformanceCounter( ) фиксируют
текущее значение таймера и заносит его в переменные a и b. Затем идет перевод этих значений в микросекунды по формуле с учетом текущей частоты работы микропроцессора, эту частоту мы получаем вызывая системную функцию QueryPerformanceFrequency(&f).
 
Вызов _sleep(0) Нужен для того, чтобы разделить хоть чем-то системные вызовы
QueryPerformanceCounter( ). Никакой дополнительной задержки она не вносит (0).
Практические эксперименты показали, что минимальная величина задержки, которую можно отмерить в Виндовс даже при всех этих ухищрениях не меньше чем половина миллисекунды, или порядка 200 - 500 микросекунд. Причем она может ещё и плавать в широких пределах, что не позволяет строить приложения, нуждающиеся в гарантированно точном определении минимальных временных интервалов.
Эксперименты проводились на достаточно быстром компе, с частотой
порядка 2-х ГГц.
 
Вот вам и мой ответ на тему какая система лучше.
Если судить по таймерной реализации, то с этой точки зрения вывод очевиден.
Маздай,- он и есть маздай :))
Именно по этой причине линукс находится в фаворе в плане реализации аккустической системы.
То есть аудиопроигрыватель линукса с самого начала был намного качественней, чем в
Виндах. А Винамп только в WinXP c трудом отучили заикаться при малейшей фоновой
активности. Да и то не на все 100%. Рецидивы ещё бывают.
P.S. Кто знает способ получения под виндой наносекундных задержек,
напишите его мне, буду признателен.

Новые материалы на сайте:
в раздел "разное" добавлена моя статья на тему использования
функции PGP в почтовом клиенте The Bat!
 
 
Туда же добавлена выдержка из очень интересной дискуссии форума
Rus21. Я получил большое удовольствие от чтения, надеюсь, что
и вам понравится.
 
Что касается темы защиты информации, то по мере накопления материала
на сайте будет организован специальный раздел. А пока пусть лежит
в разделе "разное"
 
В заключение сделаю небольшое
объявление:
 
Ищу программистов для совместного выпуска программного обеспечения
и создания в перспективе аутсорсинговой фирмы. Направления деятельности:
коммерческие веб-порталы, базы данных, распределенные системы
документооборота. Преимущество проживающим в Питере.
Потребуются также менеджер(ы). Подробнее - на главной странице сайта.
Я выступаю как координатор проекта. У кого есть идеи и предложения - пишите. 

kennobi 07.05.06
E-mail:   reshebnik(собака)rambler(точка)ru
(c) Copyright 2004-2006 http://www.reshebnik.net.ru

В избранное