Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Система";
Текущий архив: 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.008 c
6-28963
koly01
2002-12-17 11:29
2003.02.10
ПОМОГИТЕ!!! Server accept Client


3-28636
ANDR
2003-01-23 14:12
2003.02.10
Клик на заголовке.


1-28727
Юный_программер
2003-01-29 19:46
2003.02.10
Как допустим кнопку программно отцентровать в форме по центру (вс


1-28708
Colonel Isaev
2003-01-31 14:50
2003.02.10
Вопрос по системе


6-28953
FDel
2002-12-16 16:04
2003.02.10
IP-адрес





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский