У тебя возникнут следующие трудности:
1. Если выдерживать времянку не поллингом, а все-таки с помощью
какого-нибудь таймера, то ты привязан к тикам системного таймера. Они,
если я не ошибаюсь, имеют в NT/XP частоту 100 Hz. Если же использовать
поллинг, то CPU time будет расходоваться впустую
2. Тебя может прерывать всякая разная системная активность. Совершенно
не обязятельно, что сетевая. Это может быть, например, подкачка с диска.
Это может добавлять задержки вплоть до единиц миллисекунд (редко — до
десятков) в совершенно неожиданные моменты времени. Для user space
процессов ситуация хуже, т.к. они конкурируют с другими процессами. Но
даже перетаскивание твоего кода в ядро (например, в NDIS'овский
протокольный драйвер) не очень поможет.
3. У сетевого драйвера есть своя очередь, и ты не можешь управлять ей.
Если там уже лежит 100 пакетов, твой будет 101-м. Приоритеты пакетов
поддерживаются далеко не всеми драйверами.
4. На принимающей стороне могут быть свои задержки.
5. Коллизии в сети тоже вносят свой вклад. Пакет размером 1500 байт
передается на скорости 10 mbps в течении 1.2 мс. В тот момент, когда
пришла пора передавать твой пакет, сеть может быть занята чужим пакетом.
Даже в 100 mbps сети встречаются 10-мегабитные пакеты, если там есть
хоть одно 10-мегабитное устройство.
В общем, лучше не рассчитывать на возможность посылать пакеты с точной
времянкой.
qqqqq wrote: > > From: *qqqqq* </Users/Profile.aspx?uid=14500> </search/?group=11> > </Users/Private/AddFav.aspx?mid=1420793> <NewMsg.aspx?gid=11> > <NewMsg.aspx?mid=1420793> <?mid=1420793> > <Message.aspx?mid=1420793#1420793> <NewMsg.aspx?mid=1420793&edit=1> > <Private/Self.aspx?mid=1420793> > > Мне надо из моей программы перидодически посылать UDP пакеты с > достаточно точным периодом от 19 до 21 ms. Предположим я сделаю > планировщик в проге более-менее стабильный. Но даже если я буду посылать > UDP сообщения в winsock с идеально точной частотой, то кто же его знает > какую задержку этот winsock внесет и главное насколько сильно эта > задержка будет меняться от случая к случаю. Я так понимаю в Windows > должны быть какие нибудь потоки/процессы/драйверы/и т.д. и т.п. которые > передают сообщения от уровня к уровню, и когда оно до сетевой карты > дойдет и та его наконец пошлет наружу в провод никому не известно. > Я думаю, а может ну этот winsock нафик и просто самому UDP пакет собрать > во всеми UDP/IP/и т.д. полями и послатъ его через WinPcap или raw > socket? WinPcap должен быть побыстрее winsock'а потому что он вроде > напрямую с драйвером общается. Правда с фрагментации UDP пакетов в > WinPcap'е нет . А есть ли какая нибудь платная сетевая библиотека (или > драйвер) которая бы была а-ля реал тайм и еще с UDP > фрагментацией/дефрагментацией? Нашел вот Packet Sniffer SDK > www.microolap.com <http://www.microolap.com> он хоть и сниффер но > посылать тоже умеет. Кто нибудь ей пользовался? Как она в смысле > быстродействия? Или еще что нибудь кто нибудь посоветует? > Послать UDP сообщение по быстрому <?mid=1420793> Оценить > <RateList.aspx?mid=1420793> <Private/Rate.aspx?mid=1420793&rate=-3> > <Private/Rate.aspx?mid=1420793&rate=1> > <Private/Rate.aspx?mid=1420793&rate=2> > <Private/Rate.aspx?mid=1420793&rate=3> > <Private/Rate.aspx?mid=1420793&rate=-1> > <Private/Rate.aspx?mid=1420793&rate=-2> > <Private/Rate.aspx?mid=1420793&rate=-4> > <Private/Rate.aspx?mid=1420793&rate=0> >
On Fri, 07 Oct 2005 13:02:33 +0400, Mr. None <13153@users.rsdn.ru> wrote:
> Здравствуйте, qqqqq, Вы писали: > > MN>>Не сможете. Даже в режиме ядра минимальная временная погрешность (один тик) определённый MS равен 20 ms (на практике он как правило не достижим, обычно погрешность больше). Что это означает: в исключительных условиях (на ооочень быстрой машине и с благоприятной фазой луны) в вашем драйвере вы сможете отсчитывать время с точность до 20 ms (ваш таймер будет срабатывать каждые 20ms — 20ms, 40ms, 60ms и т.д.) большая точность простосто не достижима! Так что забудьте от 19ms или 21ms даже в режиме ядра... про user-mode я вообще молчу... > > Q>По моему, Ваши сведения немного устарели. > > Некоторые магические числа не могут устаревать, это как преславутые 18.2 раза в секунду — мменно с такой частотой срабатывает аппаратный таймер, настроенный по дефолту (тот который программируется через 60-ый порт)... И срабатывал он так и на старых 8086-ых, и на новых 4-ых пнях (его теоретическая точность точность, если перепрограммировать колеблется примерно в районе 1 наносекунды, практическая где-то около 10 наносекунд... мне удавалось получить результат примерно в 10, но это был ДОС). Так что нет ничего удивительного в том, что эти магические 20 мс были есть и будут под виндой... Винда не является операционкой реального времени и высокие временные точности ей не очень-то нужны.
Да, не устаревают. Только этим таймером никто уже не пользуется последние лет десять.
Сейчас пользуют Programmable Interval Timer и CPU Local Timers.
Understanding the Linux Kernel, Second Edition
6.1 Hardware Clocks
On the 80 x 86 architecture, the kernel must explicitly interact with four kinds of clocks: the Real Time Clock, the Time Stamp Counter, the Programmable Interval Timer, and the timer of the local APICs in SMP systems. The first two hardware devices allow the kernel to keep track of the current time of day. The PIC device and the timers of the local APICs are programmed by the kernel so that they issue interrupts at a fixed, predefined frequency; such periodic interrupts are crucial for implementing the timers used by the kernel and the user programs.
6.1.1 Real Time Clock
All PCs include a clock called Real Time Clock (RTC ), which is independent of the CPU and all other chips.
The RTC continues to tick even when the PC is switched off, since it is energized by a small battery or accumulator. The CMOS RAM and RTC are integrated in a single chip (the Motorola 146818 or an equivalent).
The RTC is capable of issuing periodic interrupts on IRQ 8 at frequencies ranging between 2 Hz and 8,192 Hz. It can also be programmed to activate the IRQ 8 line when the RTC reaches a specific value, thus working as an alarm clock.
Linux uses the RTC only to derive the time and date; however, it allows processes to program the RTC by acting on the /dev/rtc device file (see Chapter 13). The kernel accesses the RTC through the 0x70 and 0x71 I/O ports. The system administrator can set up the clock by executing the clock Unix system program that acts directly on these two I/O ports.
6.1.2 Time Stamp Counter
All 80 x 86 microprocessors include a CLK input pin, which receives the clock signal of an external oscillator.
Starting with the Pentium, many recent 80 x 86 microprocessors include a 64-bit Time Stamp Counter (TSC ) register that can be read by means of the rdtsc assembly language instruction. This register is a counter that is incremented at each clock signal — if, for instance, the clock ticks at 400 MHz, the Time Stamp Counter is incremented once every 2.5 nanoseconds.
Linux takes advantage of this register to get much more accurate time measurements than those delivered by the Programmable Interval Timer. To do this, Linux must determine the clock signal frequency while initializing the system. In fact, since this frequency is not declared when compiling the kernel, the same kernel image may run on CPUs whose clocks may tick at any frequency.
The task of figuring out the actual frequency of a CPU is accomplished during the system's boot. The calibrate_tsc( ) function computes the frequency by counting the number of clock signals that occur in a relatively long time interval, namely 50.00077 milliseconds. This time constant is produced by properly setting up one of the channels of the Programmable Interval Timer (see the next section). The long execution time of calibrate_tsc( ) does not create problems, since the function is invoked only during system initialization.[1]
[1] To avoid losing significant digits in the integer divisions, calibrate_tsc( ) returns the duration, in microseconds, of a clock tick multiplied by 232.
6.1.3 Programmable Interval Timer
Besides the Real Time Clock and the Time Stamp Counter, IBM-compatible PCs include another type of time-measuring device called Programmable Interval Timer (PIT ). The role of a PIT is similar to the alarm clock of a microwave oven: it makes the user aware that the cooking time interval has elapsed. Instead of ringing a bell, this device issues a special interrupt called timer interrupt, which notifies the kernel that one more time interval has elapsed.[2] Another difference from the alarm clock is that the PIT goes on issuing interrupts forever at some fixed frequency established by the kernel. Each IBM-compatible PC includes at least one PIT, which is usually implemented by a 8254 CMOS chip using the 0x40-0x43 I/O ports.
[2] The PIT is also used to drive an audio amplifier connected to the computer's internal speaker.
As we shall see in detail in the next paragraphs, Linux programs the PIT to issue timer interrupts on the IRQ0 at a (roughly) 100-Hz frequency — that is, once every 10 milliseconds. This time interval is called a tick, and its length in microseconds is stored in the tick variable. The ticks beat time for all activities in the system; in some sense, they are like the ticks sounded by a metronome while a musician is rehearsing.
Generally speaking, shorter ticks result in higher resolution timers, which help with smoother multimedia playback and faster response time when performing synchronous I/O multiplexing (poll( ) and select( ) system calls). This is a trade-off however: shorter ticks require the CPU to spend a larger fraction of its time in Kernel Mode — that is, a smaller fraction of time in User Mode. As a consequence, user programs run slower. Therefore, only very powerful machines can adopt very short ticks and afford the consequent overhead. Currently, most Hewlett-Packard's Alpha and Intel's IA-64 ports of the Linux kernel issue 1,024 timer interrupts per second, corresponding to a tick of roughly 1 millisecond. The Rawhide Alpha station adopts the highest tick frequency and issues 1,200 timer interrupts per second.
A few macros in the Linux code yield some constants that determine the frequency of timer interrupts. These are discussed in the following list.
· HZ yields the number of timer interrupts per second — that is, their frequency. This value is set to 100 for IBM PCs and most other hardware platforms.
· CLOCK_TICK_RATE yields the value 1,193,180, which is the 8254 chip's internal oscillator frequency.
· LATCH yields the ratio between CLOCK_TICK_RATE and HZ. It is used to program the PIT.
The first PIT is initialized by init_IRQ( ) as follows:
outb_p(0x34,0x43);
outb_p(LATCH & 0xff , 0x40);
outb(LATCH >> 8 , 0x40);
The outb( ) C function is equivalent to the outb assembly language instruction: it copies the first operand into the I/O port specified as the second operand. The outb_p( ) function is similar to outb( ), except that it introduces a pause by executing a no-op instruction. The first outb_ p( ) invocation is a command to the PIT to issue interrupts at a new rate. The next two outb_ p( ) and outb( ) invocations supply the new interrupt rate to the device. The 16-bit LATCH constant is sent to the 8-bit 0x40 I/O port of the device as two consecutive bytes. As a result, the PIT issues timer interrupts at a (roughly) 100-Hz frequency (that is, once every 10 ms).
6.1.4 CPU Local Timers
The local APIC present in recent Intel processors (see Section 4.2) provides yet another time-measuring device: the CPU local timer.
The CPU local timer is a device that can issue one-shot or periodic interrupts, which is similar to the Programmable Interval Timer just described. There are, however, a few differences:
· The APIC's timer counter is 32-bits long, while the PIT's timer counter is 16-bits long; therefore, the local timer can be programmed to issue interrupts at very low frequencies (the counter stores the number of ticks that must elapse before the interrupt is issued).
· The local APIC timer sends an interrupt only to its processor, while the PIT raises a global interrupt, which may be handled by any CPU in the system.
· The APIC's timer is based on the bus clock signal (or the APIC bus signal, in older machines). It can be programmed in such a way to decrement the timer counter every 1, 2, 4, 8, 16, 32, 64, or 128 bus clock signals. Conversely, the PIT has its own internal clock oscillator.
qqqqq wrote: > > По моему, Ваши сведения немного устарели. Если бы все было бы так плохо > то тогда многие программы, которые сейчас уже стали привычными, просто > бы не работали.К тому же у Windows таймер по умолчанию настроен на 10ms > а не 20. 20мс это ну очень долго. Самый простой путь наверное будет > использовать мультимедиа таймеры см. > http://www.sysinternals.com/Information/HighResolutionTimers.html
Точность, с которой можно узнать время, выше, чем точность, с которой
можно заказать задержку.
Задержку (без цикла ожидания) можно заказать с точностью до следующего
таймерного прерывания. Я не знаю всех деталей, но думаю, что маленькие
задержки Форточки отрабатывают циклом ожидания, а большие — с помощью
прерываний от таймера. Т.д., для задержек выше некоторых точность будет
не слишком высокая. Где проходит эта граница, я не знаю.
Возможно так же, что Виндовс динамически подкручивает частоту системного
таймера в зависимости от потребностей. Это все не очень-то
документировано, так что чтобы это узнать, надо поэкспериментировать.
Результат эксперимента может различаться между разными версиями Виндовса.
Мултимедия, обратите внимание, не нуждается в очень уж точных таймерах.
В конечном итоге, точный тайминг выдерживается звуковой или видео
картой. Системе надо лишь кормить ее данными (или забирать из нее
данные) со _в среднем_ правильной точностью.
> Вообще тема таймеров и реал-таймености Windows заслуживает отдельной > ветки в разделе Низкоуровневое программирование. Здесь я бы хотел узнать > о хороших сетевых библиотеках у которых время затрачиваемое за посылку > пакета более менее постоянное.
Как я Вам уже пытался объяснить, надежным образом это сделать нельзя.
Hint: задержки в ядре на DISPATCH уровне могут доходить до единиц
миллисекунд. Что уж говорить об user space процессах!
Советую Вам более тщательно обдумать свою архитектуру, и не
закладываться на недостижимые возможности.
Здравствуйте, qqqqq, Вы писали:
Q>Я думаю стабильность периода 19-21 ms в самой проге на том компе я смогу обеспечить.
Не сможете. Даже в режиме ядра минимальная временная погрешность (один тик) определённый MS равен 20 ms (на практике он как правило не достижим, обычно погрешность больше). Что это означает: в исключительных условиях (на ооочень быстрой машине и с благоприятной фазой луны) в вашем драйвере вы сможете отсчитывать время с точность до 20 ms (ваш таймер будет срабатывать каждые 20ms — 20ms, 40ms, 60ms и т.д.) большая точность простосто не достижима! Так что забудьте от 19ms или 21ms даже в режиме ядра... про user-mode я вообще молчу...
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Мне надо из моей программы перидодически посылать UDP пакеты с достаточно точным периодом от 19 до 21 ms. Предположим я сделаю планировщик в проге более-менее стабильный. Но даже если я буду посылать UDP сообщения в winsock с идеально точной частотой, то кто же его знает какую задержку этот winsock внесет и главное насколько сильно эта задержка будет меняться от случая к случаю. Я так понимаю в Windows должны быть какие нибудь потоки/процессы/драйверы/и т.д. и т.п. которые передают сообщения от уровня к уровню, и когда оно до сетевой карты дойдет и та его наконец пошлет наружу в провод никому не известно.
Я думаю, а может ну этот winsock нафик и просто самому UDP пакет собрать во всеми UDP/IP/и т.д. полями и послатъ его через WinPcap или raw socket? WinPcap должен быть побыстрее winsock'а потому что он вроде напрямую с драйвером общается. Правда с фрагментации UDP пакетов в WinPcap'е нет . А есть ли какая нибудь платная сетевая библиотека (или драйвер) которая бы была а-ля реал тайм и еще с UDP фрагментацией/дефрагментацией? Нашел вот Packet Sniffer SDK www.microolap.com он хоть и сниффер но посылать тоже умеет. Кто нибудь ей пользовался? Как она в смысле быстродействия? Или еще что нибудь кто нибудь посоветует?
Я думаю стабильность периода 19-21 ms в самой проге на том компе я смогу обеспечить. Хорошо бы получить стабильную и постоянную задержку в процессе передачи данных (даже если она будет например 10 ms или 100 ms но всегда!). Никаких коллизий нет, соединение с приемником напрямую через провод.
MN>Не сможете. Даже в режиме ядра минимальная временная погрешность (один тик) определённый MS равен 20 ms (на практике он как правило не достижим, обычно погрешность больше). Что это означает: в исключительных условиях (на ооочень быстрой машине и с благоприятной фазой луны) в вашем драйвере вы сможете отсчитывать время с точность до 20 ms (ваш таймер будет срабатывать каждые 20ms — 20ms, 40ms, 60ms и т.д.) большая точность простосто не достижима! Так что забудьте от 19ms или 21ms даже в режиме ядра... про user-mode я вообще молчу...
По моему, Ваши сведения немного устарели. Если бы все было бы так плохо то тогда многие программы, которые сейчас уже стали привычными, просто бы не работали.К тому же у Windows таймер по умолчанию настроен на 10ms а не 20. 20мс это ну очень долго. Самый простой путь наверное будет использовать мультимедиа таймеры см. http://www.sysinternals.com/Information/HighResolutionTimers.html
Вообще тема таймеров и реал-таймености Windows заслуживает отдельной ветки в разделе Низкоуровневое программирование. Здесь я бы хотел узнать о хороших сетевых библиотеках у которых время затрачиваемое за посылку пакета более менее постоянное.
Здравствуйте, Pzz, Вы писали:
Pzz> 1. Если выдерживать времянку не поллингом, а все-таки с помощью Pzz>какого-нибудь таймера, то ты привязан к тикам системного таймера. Они, Pzz>если я не ошибаюсь, имеют в NT/XP частоту 100 Hz.
По умолчанию, обычно период 15мс для workstation. Его можно изменить:
/**
* @note Прототип описан у Гарри Неббет "Справочник по базовым функциям Windows NT/2000"
*
* @return STATUS_SUCCESS в случае успешного завершения.
* иначе - код ошибки, например STATUS_TIMER_RESOLUTION_NOT_SET.
*/
NTSTATUS __stdcall
NtSetTimerResolution(
/// Запрошенный период таймера в единицах по 100 наносекунд.const unsigned long RequestedResolution,
/// Определяет, должен ли запрошенный период быть установлен или отменён.const int Set,
/// Указательна переменную, получающую фактический период таймера в единицах по 100 наносекунд.unsigned long * const Actualresolution
);
Из (полу)документированных функций есть только timeBeginPeriod, но там точность меньше. Подробнее здесь
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, gear nuke, Вы писали:
GN>Здравствуйте, Mr. None, Вы писали:
MN>>Даже в режиме ядра минимальная временная погрешность (один тик) определённый MS равен 20 ms
GN>На самом деле, 100 наносекунд. GN>Re[2]: Послать UDP сообщение по быстрому
Не ну на самом деле для x86`ой архитектуры теоретически время отсчитывается с точностью примерно 1 наносекунда... Но это же не означает, что вы сможете эту точность задействовать у себя (лично я получал величины примерно равные 10 наносекундам только под ДОС и только прямым программированием системных таймеров). Так и тут — задавать то вы её можете по 100 наносекунд, вот только всё, что ниже значения в 20мс не имеет никакого смысла, потому как не гарантируется. Это как в юзер моде, теоретически задавать тики таймера можно с точностью до 1 мс, практическое же значение временного разрешения (вычисленное множественными тестами) колеблиться опять таки от преславутых 20 мс, до примерно 30 мс, верхний предел сильно зависит от тачки... но вот опуститься ниже 20мс не удавалось никогда...
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Здравствуйте, qqqqq, Вы писали:
MN>>Не сможете. Даже в режиме ядра минимальная временная погрешность (один тик) определённый MS равен 20 ms (на практике он как правило не достижим, обычно погрешность больше). Что это означает: в исключительных условиях (на ооочень быстрой машине и с благоприятной фазой луны) в вашем драйвере вы сможете отсчитывать время с точность до 20 ms (ваш таймер будет срабатывать каждые 20ms — 20ms, 40ms, 60ms и т.д.) большая точность простосто не достижима! Так что забудьте от 19ms или 21ms даже в режиме ядра... про user-mode я вообще молчу...
Q>По моему, Ваши сведения немного устарели.
Некоторые магические числа не могут устаревать, это как преславутые 18.2 раза в секунду — мменно с такой частотой срабатывает аппаратный таймер, настроенный по дефолту (тот который программируется через 60-ый порт)... И срабатывал он так и на старых 8086-ых, и на новых 4-ых пнях (его теоретическая точность точность, если перепрограммировать колеблется примерно в районе 1 наносекунды, практическая где-то около 10 наносекунд... мне удавалось получить результат примерно в 10, но это был ДОС). Так что нет ничего удивительного в том, что эти магические 20 мс были есть и будут под виндой... Винда не является операционкой реального времени и высокие временные точности ей не очень-то нужны.
Q>Если бы все было бы так плохо то тогда многие программы, которые сейчас уже стали привычными, просто бы не работали.
Какие например... Я не знаю ни одной программы под Windows, где бы были нужны такие временные точности...
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Здравствуйте, Mr. None, Вы писали:
MN>Не ну на самом деле для x86`ой архитектуры теоретически время отсчитывается с точностью примерно 1 наносекунда...
Откуда такая цифра?
MN>Но это же не означает, что вы сможете эту точность задействовать у себя (лично я получал величины примерно равные 10 наносекундам только под ДОС и только прямым программированием системных таймеров).
Если посмотреть "исходники" NtSetTimerResolution здесь
, то будет видно, что именно таймер она и перепрограммирует.
MN>Так и тут — задавать то вы её можете по 100 наносекунд, вот только всё, что ниже значения в 20мс не имеет никакого смысла, потому как не гарантируется.
Да, не гарантируются. Но практически запросто получить 2ms для юзерленда посредством WinAPI. Тестирование показывает, что значение достаточно стабильно, хотя конечно всё это зависит от приорететов чежих потоков.
MN>Это как в юзер моде, теоретически задавать тики таймера можно с точностью до 1 мс, практическое же значение временного разрешения (вычисленное множественными тестами) колеблиться опять таки от преславутых 20 мс, до примерно 30 мс, верхний предел сильно зависит от тачки...
30 — это для Server. На workstation никогда не видел цифр больше 15мс. Видел в редких случаях 10 (к этим машинам у меня не было доступа). Про это у Соломона и Руссиновича есть — ключик HKLM\SYSTEM\CurrentControlSet\Control\PriorityControl\Win32PrioritySeparation.
MN>но вот опуститься ниже 20мс не удавалось никогда...
. К сожалению, тема не вызвала особого интререса и собрать объективную статистику не удалось. Так что, пока, результатам моих тестов могу доверять только я .
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, Pzz, Вы писали:
Pzz>Задержку (без цикла ожидания) можно заказать с точностью до следующего Pzz>таймерного прерывания. Я не знаю всех деталей, но думаю, что маленькие Pzz>задержки Форточки отрабатывают циклом ожидания, а большие — с помощью Pzz>прерываний от таймера.
AFAIK все задержки, о которых можно попросить ОС, завязаны не планировщике, а он — на таймере. Если где-то и есть циклы задержек — только в дровах, и то на очень небольшие промежутки времени.
Таймером же можно управлять.
Pzz>Это все не очень-то Pzz>документировано, так что чтобы это узнать, надо поэкспериментировать.
К сожалению — да. И лучше не только эксперементировать, но и изучать логику ключевых функций.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, gear nuke, Вы писали:
GN>Здравствуйте, Mr. None, Вы писали:
MN>>Не ну на самом деле для x86`ой архитектуры теоретически время отсчитывается с точностью примерно 1 наносекунда...
GN>Откуда такая цифра?
Сорри ошибся не нано-, а микросекунд — в нулях запутался ... Тем более, раз микро-, то вообще лично меня несколько настораживает почему в наносекундах (скорее всего меньше чем 10 наносекунд вы вообще не зададите... а реально и того больше...)
Как получает — очень просто. На матери стоит кварц, который тикает с постоянной скоростью (частоту не помню), аппаратный таймер синхронизирован с этим кварцем и отсчитывает его тики, при достижении счётчиком значения 65535 счётчик сбрасывается в 0 и генерится прерывание (точнее их генерится сразу несколько, одно из них например h1C). С такими настройками прерывания генерятся примерно 18.2 раза в секунду. Далее нехитрая арифметика:
1/(18.2 * 65535) ~ 0.8 микросекунд; с учётом погрешностей (на самом деле не точно 18.2, а с небольшими отклонениями) берём примерно 1 микросекунду — именно с такой частотой теоретически может срабатывать аппаратный таймер, если его перепрограммировать на выбрасывание исключений при достижении счётчиком значения не 65535, а 1 (это делается очень просто порты 60, 61 и 62). На самом деле эксперименты показывают, что реально задать можно значение 10 — 15, меньше просто никак не влияет на результат (может сейчас уже можно и меньше, но когда я экспериментировал лет 5 назад не выходило). Эти значения остаются постоянными всегда на всех x86-ых платформах, начиная с 8086-ой — это такие хардкорные постоянные магичекие числа.
MN>>Но это же не означает, что вы сможете эту точность задействовать у себя (лично я получал величины примерно равные 10 наносекундам только под ДОС и только прямым программированием системных таймеров).
GN>Если посмотреть "исходники" NtSetTimerResolution здесь
, то будет видно, что именно таймер она и перепрограммирует.
Возможно — разбираться лень.
MN>>Так и тут — задавать то вы её можете по 100 наносекунд, вот только всё, что ниже значения в 20мс не имеет никакого смысла, потому как не гарантируется.
GN>Да, не гарантируются. Но практически запросто получить 2ms для юзерленда посредством WinAPI. Тестирование показывает, что значение достаточно стабильно, хотя конечно всё это зависит от приорететов чежих потоков.
Сорри не поверю. Мне этого добиться не удалось ни разу... А экспериментировал я много... Проверьте, может вы время в тестах не правильно расчитывали?
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Здравствуйте, gear nuke, Вы писали:
GN>Здравствуйте, Pzz, Вы писали:
Pzz>>Задержку (без цикла ожидания) можно заказать с точностью до следующего Pzz>>таймерного прерывания. Я не знаю всех деталей, но думаю, что маленькие Pzz>>задержки Форточки отрабатывают циклом ожидания, а большие — с помощью Pzz>>прерываний от таймера.
GN>AFAIK все задержки, о которых можно попросить ОС, завязаны не планировщике, а он — на таймере.
А таймер на аппаратуре, а аппаратура не может дать точность выше 1 микросекунды теоретически и примерно выше 10 микросекунд проактически... Так что как минимум заявление о 100 наносекундах ни что иное как декларация отдела маркетинга Microsoft...
GN>Если где-то и есть циклы задержек — только в дровах, и то на очень небольшие промежутки времени.
С чего вы взяли, что они будут небольшие?
Ещё раз вам завяляю: в своё время мной был поставлен эксперимент, насколько будет различаться теоретическая аппаратная точность (1 микросекунда) от практической... При проведении эксперимента между программой замерителем и аппаратурой был самый минимму другого софта, по сути его не было вообще — программа работала под ДОС и напрямую обращалась к аппаратному таймеру и контроллеру прерываний. Итог проверки: реально удалось получить точность в 10 микросекунд. Это при условии отсутствия влияния ОС!
А вы утверждаете, что такая ОС как Windows практически никак не повлияет на эти временные задержки...
Спешу вас разочаровать... как минимум на этих же таймерах (читай на тех же аппаратных прерываниях или возможно на неких других прерывниях но с IRQL точно не ниже аппаратного таймера) будут висеть две весьма ресурсоёмкие части системы:
1) планировщик задач;
2) спуллер памяти.
Они точно будут конкурировать с таймером (более чем уверен — отрабатывать они будут раньше таймера) и вносить такие временные погрешности, которые в итоге и будут отражаться в те самые пресловутые 20мс...
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Mr. None wrote:
> GN>AFAIK все задержки, о которых можно попросить ОС, завязаны не > планировщике, а он — на таймере. > > А таймер на аппаратуре, а аппаратура не может дать точность выше 1 > микросекунды теоретически и примерно выше 10 микросекунд проактически... > Так что как минимум заявление о 100 наносекундах ни что иное как > декларация отдела маркетинга Microsoft...
Микрософт нигде никому не обещал 100-наносекундную точность. 100
наносекунд, это resolution, а не precision. Т.е., свойство сугубо
интерфейса, а не реализации.
То, что они в интерфейс заложили возможность увеличивать точность в
будующем, это вполне разумный шаг. Хотя конечно, лучше бы они не
выпендривались, и использовали совместимую с UNIX'ом struct timeval
Здравствуйте, Mr. None, Вы писали:
MN>>>Не ну на самом деле для x86`ой архитектуры теоретически время отсчитывается с точностью примерно 1 наносекунда...
GN>>Откуда такая цифра?
MN>Сорри ошибся не нано-, а микросекунд — в нулях запутался ... Тем более, раз микро-, то вообще лично меня несколько настораживает почему в наносекундах (скорее всего меньше чем 10 наносекунд вы вообще не зададите... а реально и того больше...)
Я ни чего не знаю о портах таймера и как он программируется, но вот из этого куска:
похоже, что на 100 наносекунд приходится 09766 ClockTics.
Т.о. точность таймера составляет 100/9766 = 0,010239606799098914601679295515052 наносекунды. И частота кварца таймера, должно быть 97 660 000 Герц. 100MHz — это всего на порядок меньше частоты CPU, поэтому такие частые прерывания от таймера не будут иметь какой-то практической ценности, видимо поэтому и был выбран интервал с "запасом" — 100ns.
MN>Как получает — очень просто. На матери стоит кварц, который тикает с постоянной скоростью (частоту не помню), аппаратный таймер синхронизирован с этим кварцем и отсчитывает его тики, при достижении счётчиком значения 65535 счётчик сбрасывается в 0 и генерится прерывание (точнее их генерится сразу несколько, одно из них например h1C). С такими настройками прерывания генерятся примерно 18.2 раза в секунду. Далее нехитрая арифметика: MN>1/(18.2 * 65535) ~ 0.8 микросекунд; с учётом погрешностей (на самом деле не точно 18.2, а с небольшими отклонениями) берём примерно 1 микросекунду — именно с такой частотой теоретически может срабатывать аппаратный таймер, если его перепрограммировать на выбрасывание исключений при достижении счётчиком значения не 65535, а 1
MN>(это делается очень просто порты 60, 61 и 62).
Последние порты, которые програмил были у ВГ93 и AY8912, и догадывыюсь, что там всё немного сложнее чем 5 слов . Наверняка даже про это где-то написан туториал на пару листов, но искать его среди массы бесполезных ссылок пока лениво. Когда найду, можно будет продолжить разговор.
MN>На самом деле эксперименты показывают, что реально задать можно значение 10 — 15, меньше просто никак не влияет на результат (может сейчас уже можно и меньше, но когда я экспериментировал лет 5 назад не выходило). Эти значения остаются постоянными всегда на всех x86-ых платформах, начиная с 8086-ой — это такие хардкорные постоянные магичекие числа.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, Pzz, Вы писали:
Pzz>Микрософт нигде никому не обещал 100-наносекундную точность. 100 Pzz>наносекунд, это resolution, а не precision. Т.е., свойство сугубо Pzz>интерфейса, а не реализации.
Можно проверить. Зачем размышлять?
Ну и исходники уже опубликованы — там всё ИМХО хорошо видно.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, Mr. None, Вы писали:
GN>>AFAIK все задержки, о которых можно попросить ОС, завязаны не планировщике, а он — на таймере.
MN>А таймер на аппаратуре, а аппаратура не может дать точность выше 1 микросекунды теоретически
По какой теории? По моей всё гораздо лучше .
MN> и примерно выше 10 микросекунд проактически... Так что как минимум заявление о 100 наносекундах ни что иное как декларация отдела маркетинга Microsoft...
Программисты тоже не подкачали .
GN>>Если где-то и есть циклы задержек — только в дровах, и то на очень небольшие промежутки времени.
MN>С чего вы взяли, что они будут небольшие?
Это требование к дизайну драйверов. DDK про это явно говорит в случаях, где pooling необходим.
MN>Ещё раз вам завяляю: в своё время мной был поставлен эксперимент, насколько будет различаться теоретическая аппаратная точность (1 микросекунда) от практической... При проведении эксперимента между программой замерителем и аппаратурой был самый минимму другого софта, по сути его не было вообще — программа работала под ДОС и напрямую обращалась к аппаратному таймеру и контроллеру прерываний. Итог проверки: реально удалось получить точность в 10 микросекунд. Это при условии отсутствия влияния ОС! MN>А вы утверждаете, что такая ОС как Windows практически никак не повлияет на эти временные задержки...
Я не только утверждаю, но и привожу результаты тестов. Вы можете их повторить и посмотреть сами.
MN>Спешу вас разочаровать... как минимум на этих же таймерах (читай на тех же аппаратных прерываниях или возможно на неких других прерывниях но с IRQL точно не ниже аппаратного таймера) будут висеть две весьма ресурсоёмкие части системы:
У таймера практически самое высокое IRQL из возможных. Выше Inter-processor interrupt, Power fail и High (последнее AFAIK используется только в KeBugCbeckEx и для маскировки всех прерывания.)
MN>1) планировщик задач;
Он вызывается так HalpClockInterrupt (RealTime Clock Interupt Service Routine) -> KeUpdateSystemTime. Последняя вызывает KiSwapThread не каждый свой вызов.
MN>2) спуллер памяти.
Это что такое?
MN>Они точно будут конкурировать с таймером (более чем уверен — отрабатывать они будут раньше таймера) и вносить такие временные погрешности, которые в итоге и будут отражаться в те самые пресловутые 20мс...
Уверенность на чём основывается? ИМХО тут более уместно было бы сказать ИМХО .
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
On Fri, 07 Oct 2005 04:42:50 +0400, Pzz <43064@users.rsdn.ru> wrote:
> Возможно так же, что Виндовс динамически подкручивает частоту системного > таймера в зависимости от потребностей.
Сомневаюсь, что это сделано в виндозе. В линуксе частота interval timer устанавливается на этапе копиляции (100, 250 (по-умолчанию), 1000 гц для FC4).
The APIC's timer is based on the bus clock signal (or the APIC bus signal, in older machines). It can be programmed in such a way to decrement the timer counter every 1, 2, 4, 8, 16, 32, 64, or 128 bus clock signals. Conversely, the PIT has its own internal clock oscillator.
> GN>Если где-то и есть циклы задержек — только в дровах, и то на очень небольшие промежутки времени. > > С чего вы взяли, что они будут небольшие?
Здравствуйте, MaximE, Вы писали:
ME>Да, не устаревают. Только этим таймером никто уже не пользуется последние лет десять.
ME>Сейчас пользуют Programmable Interval Timer и CPU Local Timers.
ME>Starting with the Pentium, many recent 80 x 86 microprocessors include a 64-bit Time Stamp Counter (TSC ) register
Сорри, ошибался... Когда я экспериментировал с таймерами Pentium только-только появился и документации по нему было очень мало.
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.