Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

возвращаясь к задержкам ... [D6, Win95/98, WinXP]


Страницы:   1 2

Vallos ©   (2005-07-05 16:08:00) 

Возникла необходимость устанавливать задержку выполнения программы (и менее 1 мс). Вроде бы и хорошая реализация:

procedure Delay_(ms: double);
var
 x1, x2, freq: Int64;
begin
 QueryPerformanceFrequency(freq);
 QueryPerformanceCounter(x1);
 repeat
   QueryPerformanceCounter(x2)
 until (x2-x1 >= 0.001*ms*freq);
end;

Все четко и красиво работает (от мкс до с), единственное - когда все процессы на машине заморожены: стоит повести мышкой - четкость и красота пропадает ... RDTSC работает аналогичным образом ...
Вопрос в следующем: есть ли другие реализации без привязки к частоте процика (частота которого плавает и в 'спящем режиме') или чегото ещё...


Vallos   (2005-07-06 11:37:00) [21]

... не пробовал ... Потому что все равно больше 1 мс с дискретностью 1 мс ...
Испробовал вот что:

procedure
var
 t1, t2: TDateTime;
begin
 t1:= Now;
 repeat
//      простое действие;
   t2:= Now-t1;
 until t2 >= 0.000001157407407; // 0.1 с
 Label1.Caption:= FloatToStr(t2/0.0000115740740740740741)

- результат в Label1 был от 0,1089997 до 0,1100006...
'простое действие' можно исключить, результат тотже. Можно ли как-то процес ускорить (делать не через Now).
Интересная деталь: код

 t1:= Now;
 for i:= 1 to 50000 do t2:= Now-t1;
 Label2.Caption:= FloatToStr(t2/0.000011574074074074074074074)

дает результаты от 0,01500004 до 0,01600021.
Минимальное значение i, при котором еще не 0 - 32000, но и значения такие же, как и при 60000, при 65000 и выше знечение увеличивается в 2 раза ...
А как использовать таймер 8253 (или какой там стоит)?


Vallos   (2005-07-05 18:24:00) [22]

Испробую завтра timeGetTime и иже с ними, результат сообщу...
Железная реализация хороша, но требует дополнительные узлы, которые можно было бы реализовать программно ...


alpet   (2005-07-05 18:19:00) [23]

Vallos   (05.07.05 18:09) [10]
В этом случае гарантий точности никаких, но вместе с тем высокоприоритетный поток имеет большие шансы на отработку с данным  интервалом (1мс), хотя раз уж работа идет с железом - синхронизировать лучше с железом. Опять же - изучайте мультимедийные таймеры высокого разрешения - это одина из немногих возможностей задавать такую небольшую задержку. Про sleep лучше вообще забыть, эта функция не дает требуемой точности.


Vallos   (2005-07-05 18:09:00) [24]

> 2Ботвин Дмитрий: я не утверждаю, что там 1.000 мс, просто стабильно держит (смотрем спецпримочками своей реализации на осциллографе, если это интересно)...
Перебраться на другую ось проблематично, желательни иметь привязку к 'народной' ...
А слип в делфях реализуется как

{$IFDEF MSWINDOWS}
procedure Sleep; external kernel32 name 'Sleep'; stdcall;
{$ENDIF}
{$IFDEF LINUX}
procedure Sleep(milliseconds: Cardinal);
begin
 usleep(milliseconds * 1000);  // usleep is in microseconds
end;
{$ENDIF}

как видно, альтернатива usleep - kernel32...


Игорь Шевченко   (2005-07-05 18:05:00) [25]


> Если важна точность


Ее надо реализовать аппаратно.


alpet   (2005-07-05 17:43:00) [26]

Если важна точность - придется перебираться на другую ось, например Qnx или Dos. Под Windows нет возможности работать с оборудованием в режиме реального времени.


Ботвин Дмитрий   (2005-07-05 17:05:00) [27]

А ты что замерял чем-то этот интервал? С чего ты взял, что
Sleep обеспечивает задержку в 1мс? Если передал ей такой параметр, это не значит, что твой поток замер ровно на 1мс. Если в этот момент времени появился в списке планируемых потоков поток
с более высоким приоритетом, то планировщик потоков именно ему
выделит квант процессорного времени, а твой продолжит работать тока после него и реальная задержка может оказаться гараздо больше чем 1мс....


Digitman   (2005-07-05 17:03:00) [28]


> Vallos   (05.07.05 17:00) [5]


> для работы с внешними устройствами


для работы с периферией, требующей такую временную дискретность и прецизионность Win32 никаким боком не подходит - нужна риэл-тайм опер.система, хоть тот же ДОС


Vallos   (2005-07-05 17:00:00) [29]

... согласен, что QueryPerformanceCounter не катит, а что катит?
> 2 Digitman: для работы с внешними устройствами...
2All: кстати, sleep(x) вполне корректно спавляется с поставленной задачей, правда только от 1 мс, с дискретностью 1 ...


Ботвин Дмитрий   (2005-07-05 16:48:00) [30]

Кстати, такие задержки с помощью QueryPerformanceFrequency
и QueryPerformanceCounter не реализовать. Они принимают допущения, что твой поток не вытесняется более приоритетными, а
работает не прерывно. Поэтому движения мышкой и нарушают всю красоту, как ты говоришь. Этот поток и куча других, более приоритетных, будут вносить погрешности...


Ботвин Дмитрий   (2005-07-05 16:44:00) [31]

А-га, и причём в среде с вытесняющей многозадачностью, где
каждому потоку тока по 20мс, примерно, отводится процессорного
времени :-)))


Digitman   (2005-07-05 16:30:00) [32]


> Vallos


> менее 1 мс


а можно полюбопытствовать, за каким лядом такая дискретность понадобилась в мультизадачной(а не риэл-тайм) среде ?


alpet   (2005-07-05 16:24:00) [33]

Тебе вероятно нужно изучить мультимедийные таймеры - они позволяют оперировать такими задержками.

functions:
timeBeginPeriod
timeEndPeriod
timeGetDevCaps
timeGetSystemTime
timeGetTime
timeKillEvent
TimeProc
timeSetEvent


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо