Страница 1 из 2

Sleep() в мкс

СообщениеДобавлено: 06.05.2010 17:41:09
Brainenjii
Потребовалась задержка в мкс. В принципе реализовал через
Код: Выделить всё
{$asmmode INTEL}

Function GetRDTSC :Int64;
Begin
  asm
    RDTSC
  end;
End;

Procedure BMyThread.Execute;
Begin
  While Not(Terminated) Do
    Begin
      If GetCPUTick - bCounter > 1700000 Then //1700000 получено экспериментально
        Begin
          bCounter := GetCPUTick;
          Inc(bStep);
          aStringList.Add(IntToStr(bStep));
          If bStep > 10 Then Synchronize(@AddStep);
        End;
    End;
End;

Но сжирается весь проц. Есть ли аналог для Sleep?

Re: Sleep() в мкс

СообщениеДобавлено: 06.05.2010 17:59:28
IBAH3XYCTA
Если Вьі используете стооль мальіе задержки и у Вас время - критичньій параметр, то лучше использовать отдельньіе потоки с вьісокими приоритетами в которьіх следует гонять цикльі и считать разницу во времени согласно Вашим требованиям. И вообще, при работе с железом лучше все делать в отдельньіх потоках. Ведь обьічно столь мальіе задержки нужньі при работе с железом ;).

Re: Sleep() в мкс

СообщениеДобавлено: 06.05.2010 18:19:50
Brainenjii
В отдельном потоке всё и делается, но без Sleep все-равно сжирается 80-90% ЦПУ

Re: Sleep() в мкс

СообщениеДобавлено: 06.05.2010 18:24:48
FeodoR
Я для себя делал так:
Код: Выделить всё
function GetUNIXTime: extended;
{Получение времени ОС в секундах с точностью до 1 мкс с 01.01.1970 00:00:00  }
var
TV : timeval;
TZ : timezone;
begin
fpGetTimeOfDay(@TV, @TZ);
{Получение времени UNIX без учёта временного сдвига ОС                        }
{Целая часть - секунды от 01.01.1970                                          }
{Дробная - микросекунды текущей секунды на момент получения времени           }
GetUNIXTime := TV.tv_sec + TV.tv_usec/1000000;
end;

procedure Delay(_dT: extended);
{Временная задержка на заданное количество секунд                            }
{  Входной параметр:                                                         }
{   _dT : extended - величина временной задержки в секундах                  }
var
cT : extended;
begin
cT:=GetUNIXTime;
while (cT+_dT)>=GetTimeGMT do;
end; 


Но в принципе это то же самое. Только не надо тики процессора подбирать.

Re: Sleep() в мкс

СообщениеДобавлено: 06.05.2010 18:30:56
Mr.Smart
Brainenjii
Sleep(0)?

Re: Sleep() в мкс

СообщениеДобавлено: 06.05.2010 18:38:53
FeodoR
Sleep(0) даст задержку на 2 мкс (что, как я понимаю, равно времени вызова функции и возвращению). + Sleep принимает время до 1 мс. Но даже при попытке встать на 1 мс стандартная функция даёт погрешность примерно в 15 мкс.

Re: Sleep() в мкс

СообщениеДобавлено: 06.05.2010 18:42:21
Brainenjii
15 мкс вполне терпимо. Благодарю.

Re: Sleep() в мкс

СообщениеДобавлено: 06.05.2010 18:44:18
FeodoR
15 мкс это погрешность.
А минимально возможная задержка при выполнении Sleep() - 1 мс.

Те функции, что я выше приложил дают погрешность 1..2 мкс. И тормозиться можно минимум на 1 мкс. :)

Re: Sleep() в мкс

СообщениеДобавлено: 06.05.2010 18:52:34
Mr.Smart
Тут проблема как я понимаю, отдать квант времени другому процессу? Или нет?

Re: Sleep() в мкс

СообщениеДобавлено: 06.05.2010 18:53:49
Brainenjii
Именно. Как-то нехорошо занимать весь процессор. Обмен по порту ведь будет почти постоянный...

Re: Sleep() в мкс

СообщениеДобавлено: 06.05.2010 19:11:27
FeodoR
А можно чуть подробнее про приложение. Что делает, сколько потоков и на какое время надо вставать.

Можно же сделать некое подобие диспетчера. То есть ещё один поток (или цикл в родительском приложении), который будет "будить" потоки при достижении времени их "просыпания". А поток, отработав свою задачу будет засыпать, оставляя время своего "пробуждения" диспетчеру. Тогда будет выполняться то, что должно выполняться, а всё остальное будет приостановлено.

Re: Sleep() в мкс

СообщениеДобавлено: 06.05.2010 19:21:01
скалогрыз
:shock: обалдели космонавты! Кто ж на орбите спит?! РАБОТАЙТЕ! упадёт станция! :mrgreen:

по сабжу. точность "обычных" ОС обычно измеряется в миллисекундах. Всё что точнее - удел ОСей реального времени (хвала QNX)! думается у них соответствующие инструменты имеются.

А так, в "обычной" системе, задержка при переключении между процессами может значительно больше, чем требуемая точность... Хотя можно попробовать дрова соответствующие пописать (и выставить приоритет процессу REALTIME),
Имхо, шкурка выделки не стоит. А всё потому, что даже если и удастся добиться требуемого результата на конкретной системе, с конкретным железом (и дровами), то очень маловероятно, что программа будет работать точно так же на другой системе с другими железо-софтверными- параметрами.

Re: Sleep() в мкс

СообщениеДобавлено: 06.05.2010 19:32:59
FeodoR
Внутри одной программы можно "привстать" на время меньшее, чем 1 мс. Что мы с успехом пользуем :)
А жёсткое РВ на писюках вообще вещь скользкая и, ИМХО, несбыточная. Потому как архитектура такая. Но, повторюсь, в пределах нескольких мкс можно обеспечить точность. Естественно при соблюдении простых правил как то, например, отсутствие дискового обмена.

Re: Sleep() в мкс

СообщениеДобавлено: 06.05.2010 19:56:48
FedeX
Я думаю можно легко получить задержку в 15-20мкс если привязаться к вертикальной синхронизации экрана - муторно, но если очень надо... :mrgreen:
Для этого надо создать невидимый контекст для OpenGL, проинициализировать как надо и в каждой итерации цикла делать wglSwapBuffer..
Недостатки: (wgl)SwapBuffer будет аппаратно(системно?) приостанавливать поток только под Windows - не помню точно но кажеться в Linux VSync работает по другому принципу и получить эффекта засыпания не получиться; также драйвера могут не поддерживать VSync (это легко проверяеться), или быть настроены на его игнорирование (это хуже), ну и самый основной недостаток - задержка слабо подвластна контролю, всё зависит от частоты экрана.

Re: Sleep() в мкс

СообщениеДобавлено: 06.05.2010 20:11:57
FeodoR
Задержку можно (повторюсь) организовать до 1 мкс в Linux штатными функциями, в Win - надо использовать либо тики процессора, либо использовать библиотеки, позволяющие получить точное время. Либо пробовать HPET, но с ним не работал, поэтому утверждать что-либо не могу.