Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.02.10;
Скачать: CL | DM;

Вниз

Время (высокоточное)   Найти похожие ветки 

 
Чегермек ©   (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;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.026 c
3-28642
John
2003-01-23 14:24
2003.02.10
Експорт/Импорт и DBGrid


7-29108
Zombik666
2002-12-04 14:03
2003.02.10
*.Scr


6-28959
antix
2002-11-17 06:50
2003.02.10
Запуск приложения (exe) у клиента


1-28800
borg
2003-02-02 10:02
2003.02.10
Извините за глупый вопрос!


1-28866
BLooDMaN
2003-01-29 23:28
2003.02.10
Как отловить нажатие F2 в собственной программе??