Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Функция Sleep(); 
V
    Опции темы
profesiachuvak
Дата 30.11.2009, 18:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 283
Регистрация: 7.11.2009
Где: Беларусь, Минск

Репутация: нет
Всего: 4



Прочитал Ваши советы по поводу RDTSC. Заинтересовало, решил испробовать. Не совсем порнятно как теперь с этой функций работать:
Код

 function RDTSC: comp;
 var TimeStamp: record case byte of
                  1: (Whole: comp);
                  2: (Lo, Hi: cardinal);
                end;
 begin
   asm
     db $0F; db $31;
     mov [TimeStamp.Lo], eax
     mov [TimeStamp.Hi], edx
   end;
   Result := TimeStamp.Whole;
 end;


К примеру посмотреть за которое время проходит цикл? И что за результат возвращает фукция? Кол-во тактов?  smile

Добавлено @ 18:41
Цитата(source777 @ 30.11.2009,  12:30)
только не забудь своей программе приоритет повыше поставить, чтобы Windows не могла на другие пользовательские программы переключаться во время работы твоей.

source777, Вы имеете ввиду что-то вроде этого ?

Код

var
  ProcessID: DWORD;
  ProcessHandle: THandle;
  ThreadHandle: THandle;
begin
  ProcessID := GetCurrentProcessID;
  ProcessHandle := OpenProcess(PROCESS_SET_INFORMATION,
    false, ProcessID);
 
SetPriorityClass(ProcessHandle, HIGH_PRIORITY_CLASS);
ThreadHandle := GetCurrentThread;
SetThreadPriority(ThreadHandle,THREAD_PRIORITY_TIME_CRITICAL);




Это сообщение отредактировал(а) profesiachuvak - 30.11.2009, 18:42


--------------------
Закон Мерфи :если есть вероятность того, что какая-нибудь неприятность может случиться, то она обязательно произойдет.
PM MAIL   Вверх
source777
Дата 30.11.2009, 19:41 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1878
Регистрация: 12.3.2007

Репутация: 4
Всего: 56



Цитата(profesiachuvak @  30.11.2009,  18:30 Найти цитируемый пост)
source777, Вы имеете ввиду что-то вроде этого ?
Нечто похожее, я на Delphi уже года 2 ничего не писал, так что с конкретным кодом сам разберёшься, главное идея.

Цитата(profesiachuvak @  30.11.2009,  18:30 Найти цитируемый пост)
К примеру посмотреть за которое время проходит цикл? И что за результат возвращает фукция? Кол-во тактов? 

Лучше с WinAPI начни.

Я имею в виду что-то типа такого:
Код

ClearDeltaTime;
while (true)
begin
  if (Abs(GetDeltaTimeInMicroseconds - 100) < 5) then 
  begin
    ClearDeltaTime;
    ReadDataFromLPT;
  end
end


GetDeltaTimeInMicroseconds будет с помощью QueryPerformanceCounter считать время между полезными итерациями.




--------------------
Если бы программистам платили за то, чтобы убирать код из программы вместо того, чтобы добавлять его, программы были бы намного лучше © Николас Негропонте
PM MAIL   Вверх
profesiachuvak
Дата 3.12.2009, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 283
Регистрация: 7.11.2009
Где: Беларусь, Минск

Репутация: нет
Всего: 4



Цитата(source777 @ 30.11.2009,  19:41)
Я имею в виду что-то типа такого:
Код

ClearDeltaTime;
while (true)
begin
  if (Abs(GetDeltaTimeInMicroseconds - 100) < 5) then 
  begin
    ClearDeltaTime;
    ReadDataFromLPT;
  end
end


GetDeltaTimeInMicroseconds будет с помощью QueryPerformanceCounter считать время между полезными итерациями.


Что ж разобрался с QueryPerformanceFrequency и QueryPerformanceCounter. Довольно удобный счётчик. Реализовал его я так : 

Код

...
var
ClockRate,StartTime,TimeElapsed:real;
t1,t2,a : TLargeInteger;
begin
QueryPerformanceFrequency(t1);
ClockRate:=t1/4;
QueryPerformanceCounter(t2);
StartTime:=t2/4;
//тут ставим нечто типа длинного цикла


//-------------------------------------
QueryPerformanceCounter(t2);

TimeElapsed:=(t2/4-StartTime)/ClockRate; // Вот результат выполнения в секундах.
 
end;


Спасибо Вам (в частности source777)  за совет насчет WinApi. Вот только теперь возник новый вопрос : И как же я смогу с помощью этого таймера сделать задержку примерно в 1 мкс?

Это сообщение отредактировал(а) profesiachuvak - 3.12.2009, 13:58


--------------------
Закон Мерфи :если есть вероятность того, что какая-нибудь неприятность может случиться, то она обязательно произойдет.
PM MAIL   Вверх
source777
Дата 3.12.2009, 18:45 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1878
Регистрация: 12.3.2007

Репутация: 4
Всего: 56



Цитата(profesiachuvak @  3.12.2009,  12:49 Найти цитируемый пост)
t1/4
почему деление на 4?

Цитата(profesiachuvak @  3.12.2009,  12:49 Найти цитируемый пост)
И как же я смогу с помощью этого таймера сделать задержку примерно в 1 мкс?

1) Я ж тебе уже описал алгоритм на псевдокоде, куда уж подробнее?
2) Помнится тебе нужно было 100 мкс



Это сообщение отредактировал(а) source777 - 3.12.2009, 18:46


--------------------
Если бы программистам платили за то, чтобы убирать код из программы вместо того, чтобы добавлять его, программы были бы намного лучше © Николас Негропонте
PM MAIL   Вверх
profesiachuvak
Дата 6.12.2009, 23:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 283
Регистрация: 7.11.2009
Где: Беларусь, Минск

Репутация: нет
Всего: 4



Цитата(source777 @ 3.12.2009,  18:45)
Цитата(profesiachuvak @  3.12.2009,  12:49 Найти цитируемый пост)
t1/4
почему деление на 4?

В темке где было написано про работу QueryPerfomanceCounter была строчка :
Код

 t1.QuadPart;

Как я понял это четвёртая часть числа, просто в такой записи у меня не работает. (t1/4 работает и результат выводит правильно)

Добавлено через 5 минут и 36 секунд
Цитата(source777 @ 3.12.2009,  18:45)
1) Я ж тебе уже описал алгоритм на псевдокоде, куда уж подробнее?
2) Помнится тебе нужно было 100 мкс

source777, я прошу прощения за то что прошу всё разжевать, но можешь немного прокомментировать свой псевдокод?
Например мне не совсем понятна вот эта строчка : 
Код

 if (Abs(GetDeltaTimeInMicroseconds - 100) < 5) then 

Остальное вроде понятно. 
Впринципе мне сойдёт задержка и в 100 мкс, но я думаю если Вы мне объясните эту строчку у меня получится сделать и 1 мкс.


--------------------
Закон Мерфи :если есть вероятность того, что какая-нибудь неприятность может случиться, то она обязательно произойдет.
PM MAIL   Вверх
source777
Дата 7.12.2009, 00:08 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1878
Регистрация: 12.3.2007

Репутация: 4
Всего: 56



А что конкретно непонятно в этой строчке? Просто я не знаю с какой точностью у тебя получится определять задержку в микросекундах, поэтому там и поставлено условие для точности +/- 4 мкс и задержки 100 мкс, числа в этой строке чисто для примера, можешь менять их эмпирическим путём.


Цитата(profesiachuvak @  6.12.2009,  23:17 Найти цитируемый пост)
Как я понял это четвёртая часть числа

 smile 
вообще-то это обращение к union типу LARGE_INTEGER из C++... 
В Delphi в сигнатуре этого метода скорее всего значится Int64, так как union в Delphi не поддерживаются, поэтому делить ни на что не надо. 

P.S. Кстати, какое значение выдаёт функция QueryPerformanceFrequency?


--------------------
Если бы программистам платили за то, чтобы убирать код из программы вместо того, чтобы добавлять его, программы были бы намного лучше © Николас Негропонте
PM MAIL   Вверх
kuzyara
Дата 7.12.2009, 08:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 215
Регистрация: 13.11.2006

Репутация: нет
Всего: 1



а зачем изобретать велосипед?
--------------------
подпись
PM MAIL   Вверх
source777
Дата 7.12.2009, 13:32 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1878
Регистрация: 12.3.2007

Репутация: 4
Всего: 56



Цитата(kuzyara @  7.12.2009,  08:55 Найти цитируемый пост)
а зачем изобретать велосипед? 

А слабо привести ссылку на готовое, юзабельное решение для сверхточного таймера, а не на сборку статей с описанием велосипедов, половина из которых вообще даже близко не соответствует условию поставленной задачи, а в оставшейся половине статей(вместе взятых) полезной информации не больше, чем в этой теме?


--------------------
Если бы программистам платили за то, чтобы убирать код из программы вместо того, чтобы добавлять его, программы были бы намного лучше © Николас Негропонте
PM MAIL   Вверх
profesiachuvak
Дата 7.12.2009, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 283
Регистрация: 7.11.2009
Где: Беларусь, Минск

Репутация: нет
Всего: 4



Цитата(source777 @ 7.12.2009,  00:08)
вообще-то это обращение к union типу LARGE_INTEGER из C++... 
В Delphi в сигнатуре этого метода скорее всего значится Int64, так как union в Delphi не поддерживаются, поэтому делить ни на что не надо. 

P.S. Кстати, какое значение выдаёт функция QueryPerformanceFrequency?

Насчёт этого деления на 4 : 
Вот к примеру тот код который я приводил для работы с таймером, только в середину я вставил слип на 1000 мс (1сек) :

Код

...
var
ClockRate,StartTime,TimeElapsed:real;
t1,t2,a : TLargeInteger;
begin
QueryPerformanceFrequency(t1);
ClockRate:=t1/4;
QueryPerformanceCounter(t2);
StartTime:=t2/4;
//тут я поставил спячку, чтобы проверить правильность выполнения операции в секундах
sleep(1000);
//-------------------------------------
QueryPerformanceCounter(t2);
TimeElapsed:=(t2/4-StartTime)/ClockRate; // Вот результат выполнения в секундах. 
 
end;


Ответ в секундах  = 0,999657498369206  
QueryPerformanceFrequency(t1); возвращает значение = 3579545

Теперь я убрал деление на 4 ответ всё тот же, Вы правы оно собственно ни к чему. На счёт вашего псевдокода: как я понял задержку мне придётся делать только с помощью цикла? Честно говоря я не совсем понимаю суть. У меня есть цикл, в котором выполняется предположим одна функция: 
Код

 for i:=1 to 10 do
                          begin
                          WriteToLptPort(1);  //короче включить первый контакт на порте
                          DelayInMicrosecond(100);//вот то что мне надо !!! Аналог sleep(); только для мкс !!!
                          end;

Ну никак моя голова не может понять, как мне грамотно использовать таймер, который я написал, чтобы это сделать.


--------------------
Закон Мерфи :если есть вероятность того, что какая-нибудь неприятность может случиться, то она обязательно произойдет.
PM MAIL   Вверх
source777
Дата 7.12.2009, 16:26 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1878
Регистрация: 12.3.2007

Репутация: 4
Всего: 56



Цитата(profesiachuvak @  7.12.2009,  15:39 Найти цитируемый пост)
как я понял задержку мне придётся делать только с помощью цикла?

да, забудь про `for i:=1 to 10 do` и юзай бесконечный while + break по счётчику полезных итераций.


Цитата(profesiachuvak @  7.12.2009,  15:39 Найти цитируемый пост)
DelayInMicrosecond(100);//вот то что мне надо !!! Аналог sleep(); только для мкс !!!

Ну мало ли что кому надо... Ты ограничен в своих желаниях особенностями архитектуры используемой ОС. 
А когда речь идёт о микросекундах, время на выполнение твоей полезной функции должно также учитываться.


Цитата(profesiachuvak @  7.12.2009,  15:39 Найти цитируемый пост)
QueryPerformanceFrequency(t1); возвращает значение = 3579545

Ну вот, значит для твоего компьютера максимальная точность будет 0,279 мкс и надо выбирать интервалы близкие к кратным этому.


Цитата(profesiachuvak @  7.12.2009,  15:39 Найти цитируемый пост)
Теперь я убрал деление на 4 ответ всё тот же
Не мудрено, ты же и частоту и время на 4 делил и в итоговом вычислении TimeElapsed все четвёрки сокращались, так что без них результат должен быть чуточку точнее.

Цитата(profesiachuvak @  7.12.2009,  15:39 Найти цитируемый пост)
sleep(1000);
лучше тестировать на sleep(125); или sleep(250); т.к. большие интервалы времени sleep обрабатывает также неточно как и маленькие.


Это сообщение отредактировал(а) source777 - 7.12.2009, 16:30


--------------------
Если бы программистам платили за то, чтобы убирать код из программы вместо того, чтобы добавлять его, программы были бы намного лучше © Николас Негропонте
PM MAIL   Вверх
kuzyara
Дата 7.12.2009, 16:44 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 215
Регистрация: 13.11.2006

Репутация: нет
Всего: 1



Цитата(source777 @  7.12.2009,  18:32 Найти цитируемый пост)
А слабо привести ссылку на готовое, юзабельное решение для сверхточного таймера, а не на сборку статей с описанием велосипедов, половина из которых вообще даже близко не соответствует условию поставленной задачи, а в оставшейся половине статей(вместе взятых) полезной информации не больше, чем в этой теме?

Ссылку я привёл, и, если не ошибаюсь, то топикастеру нужен сверхточный таймер. Вот первый пример по теме. Угадай, откуда? Там ещё есть многофункциональные модули... А обладателю лучей поноса выше рекомендую воздержаться от такого тона, а то доведёшь до баттхерта... smile 
Код

var

WaitCal: Int64;

procedure Wait(ns: Integer);

var

Counter, Freq, WaitUntil: Int64;

begin

if QueryPerformanceCounter(Counter) then

begin

   QueryPerformanceFrequency(Freq);

   WaitUntil := Counter + WaitCal + (ns * (Freq div 1000000));

   while Counter < WaitUntil do

     QueryPerformanceCounter(Counter);

end

else

   Sleep(ns div 1000);

end;


--------------------
подпись
PM MAIL   Вверх
source777
Дата 7.12.2009, 19:13 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1878
Регистрация: 12.3.2007

Репутация: 4
Всего: 56



Цитата(kuzyara @  7.12.2009,  16:44 Найти цитируемый пост)
Ссылку я привёл. Вот первый пример по теме. Угадай, откуда?

и чем же приведённые там велосипеды заслужили статус готового, юзабельного решения? Ты хоть один из них пытался использовать в реальном, современном приложении? Сам подход выставления задержки между вызовами собственной процедуры уже в корне не верен, когда нужна большая точность, так что о юзабельности примеров из той статьи можно говорить только в теории...

Цитата(kuzyara @  7.12.2009,  16:44 Найти цитируемый пост)
WaitUntil := Counter + WaitCal + (ns * (Freq div 1000000));

эта строчка явно повысит точность, для этого ж только деления нацело на мульён и не хватало...

P.S. И воздержись от перехода на личности, пока ограничусь устным предупреждением. smile  


--------------------
Если бы программистам платили за то, чтобы убирать код из программы вместо того, чтобы добавлять его, программы были бы намного лучше © Николас Негропонте
PM MAIL   Вверх
kuzyara
Дата 7.12.2009, 19:26 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 215
Регистрация: 13.11.2006

Репутация: нет
Всего: 1



"Единственным методом определения быстродействия кода должно быть его выполнение. И только." (С) Джулиан Бакнелл
Автор кагбэ намекает... smile 

Добавлено через 9 минут и 38 секунд
 smile  smile  smile  smile  smile 

Это сообщение отредактировал(а) kuzyara - 7.12.2009, 19:34
--------------------
подпись
PM MAIL   Вверх
profesiachuvak
  Дата 7.12.2009, 23:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 283
Регистрация: 7.11.2009
Где: Беларусь, Минск

Репутация: нет
Всего: 4



Ребят, спасибо за помощь.
Вывод к которому я пришёл:
Первоначально, проблема вставшая передо мной казалось вполне выполнимой, казалось бы что может быть проще простейшей задержки на доли секунды. Оказалось что из-за  архитектуры  Windows (её замысловатые кольца приоритета), кроме того как написать нечто похожее на сверхточный таймер использую возможности процессора мы не в состоянии. Для меня даже удивление что sleep(); не может работать точно. Видно я ещё слишком мало знаю. smile  smile  smile  

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

З.Ы. Спасибо,  source777. smile 


--------------------
Закон Мерфи :если есть вероятность того, что какая-нибудь неприятность может случиться, то она обязательно произойдет.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0707 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.