Форум: "Система";
Текущий архив: 2003.02.10;
Скачать: [xml.tar.bz2];
ВнизВремя (высокоточное) Найти похожие ветки
← →
Чегермек (2002-11-30 20:55) [0]Знает ли кто-нить, как померить интервалы времени с точностью до десятков мкс?
← →
Ich Hasse (2002-11-30 21:03) [1]в смысле поставить такой таймер, который мерил бы с точностью до мс? Если да то это элементарно...
← →
Ich Hasse (2002-11-30 21:13) [2]
//------------------------------------------------------------------
// Файл: sk_timer.pas
// Описание: Функции для работы с мультимедиа таймером
//------------------------------------------------------------------
unit sk_timer;
interface
uses mmSystem, Windows, SysUtils, sk_const;
type
mmTimer = object
constructor Create(skDelay:Cardinal);
destructor Destroy;
procedure SetDelay(skDelay:Cardinal);
private
TimerID : Cardinal;
mmDelay : Cardinal;
end;
implementation
procedure Timer(uTimerID, uMessage: UINT;dwUser, dw1, dw2: DWORD) stdcall;
begin
//тут надо вставить код отсчета
end;
constructor mmTimer.Create(skDelay:Cardinal);
begin
TimerID:=timeSetEvent(skDelay,0,@Timer,0,TIME_PERIODIC);
if TimerID=0 then sle("Ошибка создания таймера");
mmDelay:=skDelay;
end;
destructor mmTimer.Destroy;
begin
if timeKillEvent(TimerID)=MMSYSERR_INVALPARAM then sle("Таймер не существует");
end;
procedure mmTimer.SetDelay(skDelay:Cardinal);
begin
if timeKillEvent(TimerID)=MMSYSERR_INVALPARAM then sle("Таймер не существует");
TimerID:=timeSetEvent(skDelay,0,@Timer,0,TIME_PERIODIC);
if TimerID=0 then sle("Ошибка создания таймера");
mmDelay:=skDelay;
end;
end.
sle - процедура устанавливающая последнюю ошибку, в принципе не нужна...
← →
Чегермек (2002-12-02 09:11) [3]не мс, а мкс !!!
← →
jack128 (2002-12-02 09:45) [4]на сколько я знаю в win это не возможно
← →
MBo (2002-12-02 13:14) [5]QueryPerformanceCounter (API функция) или RDTSC (ассемблерная команда)
← →
Igor1984 (2002-12-02 13:33) [6]Да вы гоните. Минимальный шаг таймера ibm совместимых машин 55 мс. Меньшие интервалы получить невозможно. Разве что прогнать цикл много раз в течении к примеру секунды и подсчитывать сколько раз произошла итерация, а пот посчитать среднее.
← →
MBo (2002-12-02 13:40) [7]>Igor1984
Может, кто и гонит....
Вызвать событие через точный интервал времени - нельзя,
а точно измерить промежуток времени - МОЖНО
← →
Igor1984 (2002-12-02 13:55) [8]Конечно можно, если знать что событие произошло 1000 раз за секунду. Значит оно произошло в среднем за 1 мс,так? А вот время еденичного события будет кратно 55мс всегда.
← →
MegaVolt (2002-12-02 14:28) [9]Igor1984:
ИМХО ты не прав с помощью предложенного выше примера получал задержки порядка 10мс+/- 2мс так что стабильность ни к чёрту но в некоторых приложениях бывает достаточно.
← →
jonik pegas (2002-12-02 15:23) [10]Igor1984
Не надо так категорично. Использование RDTSC позволяет мерять время между двумя событиями с точностью до такта процессора минус время выполнения самой команды. Может быть будет интересно узнать что время выполнения команды A:=sqrt(100) составляет 4.2 мкс на П4 1400, только что померял.
← →
pasha676 (2002-12-02 15:30) [11]Если я не ошибаюсь (хотя память уже у меня хырыновая), то таймер имеет тактовую частоту 1.14 МГц. Потом идет програмируемый делитель и т.д. То есть, если написать процедурку на асме, то чисто теоритически получить ИЗМЕРЕНИЕ промежутка времени можно с точностью до 1/1140000. Хотя реально точность и будет меньше, но всетаки десятки мкс наверное получить можно.
> точно измерить промежуток времени - МОЖНО
абсолютно согласен с МВо
← →
MegaVolt (2002-12-02 15:42) [12]А попробуй померять inc(A)? Если получится опять около 250КГц то это ИМХО лажа
← →
jonik pegas (2002-12-02 15:49) [13]Вот функция вычисляет число тактов процессора между сбросом и текущим моментом
function RDTSС:int64;
begin
asm
rdtsc;
mov dword ptr result,eax
mov dword ptr result[4],edx
end;
Result:=Result;
end;
Соответственно нужно вычислить pазность между двумя последовательными вызовами данной функции-это даст ее время выполнения. А затем получить разность между интерессующими событиями. Для получения времени выполнения в микросекундах необходимо знать тактовую частоту МП. В этом помогут функции QueryPerfomanceCounter/QueryPerfomanceFrequency
← →
jonik pegas (2002-12-02 16:00) [14]Не inc(A) не ловится. длительность самой функции слегка плавает, а inc(A)-это однокомандная операция. sqrt же-долгая операция
← →
MegaVolt (2002-12-02 16:24) [15]Но не столько же долгая :( Получается что производительность проца падает до 250КГц что очень и очень мало. (такие скорости можно получить и на обычных микроконтроллерах а не на проце с 1.4Г :()
← →
sw (2002-12-03 04:32) [16]Советую зайти на
http://www.torry.net/timers.htm
там множество всяких таймеров, в чсатности стоит посмотреть
HighResTimer v.1.02 и
HPTimer v.1.2
Если нужно просто измерять время - это сделать просто, прочитав счётчик тактов процессора.
Если нужно сделать таймер, то общая идея такая - создаётся отдельный поток, который проверяет этот счётчик тактов процессора на достижение наперёд заданной величины. Как только момент достигнут - вызываются действия таймера.
Экспериментально получается максимальное число срабатываний такого таймера - 30 000 раз в секунду на машине 350 МГц при нормальном приоритете потока. Видимо поток получает управление до 30000 раз в секунду. Если приоритет поднять - компьютер будет тормозить.
← →
MBo (2002-12-03 06:33) [17]>Видимо поток получает управление до 30000 раз в секунду
Эт вряд ли ;) (© тов. Сухов)
← →
zavdim (2002-12-03 09:37) [18]А в какой связи нужна такая точность - куда ее потом девать?
Если ответить зачем, то может и разберемся что делать.
Просто такты считать не совсем точно - надо еще такты на саму функцию кинуть.
← →
sw (2002-12-03 09:45) [19]извиняюсь, ошибся в 10 раз
← →
zavdim (2002-12-03 09:45) [20]2Igor1984
Если использовать простой таймер, то под 98 и Ме действительно чащее 55 мс ничего не выйдет, а вот под 2000 я уже с 20 мс свободно ходил - есть списки которые записывали время.
А мультимедийный и под 98 ходит с точностью до 10 мс, меньше не ставил - мне для игровой мультипликации 30-50 вполне хватает.
← →
jonik pegas (2002-12-03 10:01) [21]"Точность никогда не бывает лишней"(чокнуный продавец из билайна)
MegaVolt
Я не знаю чего он так корень долго считает(может функцию какую загружает), возьми и проверь. Причем это он первый корень так долго считает а если в цикл загнать for i=0 to 1000 do a:=sqrt(a) то за 52мкс обсчитывает. А посчитать корень на контроллерах ты вряд ли быстрее успеешь-4 мкс-это 16 командных тактов на AVR-не уложишься.
Кстати Inc(a) считает за менее чем 1,06 нc, потому что на for i:=0 to 10000 do inc(a) тратит 10,6 мкс. Прибавление 1 к extended занимает 22 нс ну и т.д. Хотя может он цикл круто оптимизирует и указанные цифры не верны.
← →
MegaVoltik (2002-12-03 10:50) [22]Да всё верно просто при вызове одной комманды к ней добавляется ещё какието сервисные вещи которые можно назвать просто подготовка к выполнению и получение результатов так вот при выполнении цикла это время подготовок размазывается на 1000 выполнений комманды а при 1 комманде остаётся без изменения и соответсятвенно при стремлении числа итераций к бесконечности время выполнения комманды стремится к реальному. По этому нужно очень и очень окуратно относится к таким измерениям :)
А поводу микроконтроллера я мерял по C167CR ента вещь работает на 25MIPS и следовательно получается 100 комманд что уже не так уж и мало для расчёта корня хотя всё зависит от длинны числа и точности вычисления :)
← →
zavdim (2002-12-03 11:16) [23]Так ведь при цикле и команда в кеше сидит.
← →
MegaVolt (2002-12-03 11:23) [24]А я про что :)
← →
MegaVolt (2002-12-03 16:39) [25]Выложил:
http://delphibase.endimus.ru/?action=viewfunc&topic=fileattr&id=10367
← →
MegaVolt (2002-12-03 16:40) [26]Упс... не туда :(
← →
чегермек (2002-12-04 08:49) [27]Всем большое спасибо !!! Получил массу впечатлений, а также множество решений (не только своей задачи). Особо понравились QueryPerformanceCounter и ссылочка sw. Еще раз спасибо.
Страницы: 1 вся ветка
Форум: "Система";
Текущий архив: 2003.02.10;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.009 c