Что нового

Пауза 100 мкс

VadimKHL

Новичок
Сообщения
155
Репутация
0
Всем привет!
Подскажите пожалуйста, как можно делать задержки, допустим 100 мкс или другие подобные?
Проблем в том, что цикл без задержки сильно грузит ЦП, а Sleep меньше 1 мс низя((((
 

All2khoff

Продвинутый
Сообщения
352
Репутация
65
вам нужна задержка меньше 1 тысячной секунды? вам зачем такие короткие задержки?
Код:
Функция Sleep
$hTimer [URL='https://autoit-script.ru/intro/lang_operators.htm']=[/URL] TimerInit()
Sleep(1000) ; Приостановка скрипта на 1 секунду
MsgBox(0, "Сообщение", 'Прошло время: ' & Round(TimerDiff($hTimer), 2) & ' мсек')

Я просто не представляю проекта где нужна задержка но 1 тысячная секунды
Код:
Sleep(1)

была бы избыточна.
обычно паузы нужны как раз для отработки процессов со стороны операционной системы
 

Oki

Продвинутый
Сообщения
452
Репутация
62
В реальности даже задержка на миллисекунду проблематична, поскольку пробуждение процесса из сна происходит за счёт синхронных прерываний от системных часов, периодичность которых куда менее часта, чем 1000 раз в секунду. Обычной частотой таких прерываний является величина 64 Гц, тогда интервал между такими прерываниями установлен в 15,625 миллисекунд, в результате чего инструкция засыпания на одну миллисекунду фактически может выполняться случайное время от одной миллисекунды до 16,625. Учитывая же тот факт, что в AutoIt вообще реально воспринимаемый параметр функции Sleep() не может быть меньшим 10, время выполнения инструкции Sleep(1) оказывается случайным в промежутке от 10 до 25,625 миллисекунд.

Процессор больше всего нагружает не беспрерывное выполнение, а какая-то конкретная требовательная к ресурсам инструкция. Можно разбавить её нетребовательными к ресурсам инструкциями, которые растрачивают время. Например, пустым циклом повторений, которые на уровне процессора будут лишь инкрементировать счётчик и сверять его значение с конечным. Поскольку сформулированные в стартовом посте цели не предполагают выполнение в течение заданного времени, не столь важна длительность этой задержки (она может в такой реализации зависеть от мощности компьютера и его загруженности другими задачами).
Сообщение автоматически объединено:

Два следующих скрипта демонстрируют непедантичность времени задержки в результате применения функции Sleep().
Код:
$hTimer = TimerInit()
$fDiff1 = TimerDiff($hTimer)
Sleep(1)
$fDiff2 = TimerDiff($hTimer)
Sleep(1)
$fDiff3 = TimerDiff($hTimer)
Sleep(1)
$fDiff4 = TimerDiff($hTimer)
Sleep(1)
$fDiff5 = TimerDiff($hTimer)
Sleep(1)
$fDiff6 = TimerDiff($hTimer)
Sleep(1)
$fDiff7 = TimerDiff($hTimer)
Sleep(1)
$fDiff8 = TimerDiff($hTimer)
Sleep(1)
$fDiff9 = TimerDiff($hTimer)
Sleep(1)
$fDiff10 = TimerDiff($hTimer)
Sleep(1)
$fDiff11 = TimerDiff($hTimer)
Sleep(1)
$fDiff12 = TimerDiff($hTimer)
Sleep(1)
$fDiff13 = TimerDiff($hTimer)
Sleep(1)
$fDiff14 = TimerDiff($hTimer)
Sleep(1)
$fDiff15 = TimerDiff($hTimer)
Sleep(1)
$fDiff16 = TimerDiff($hTimer)
Sleep(1)
$fDiff17 = TimerDiff($hTimer)
Sleep(1)
$fDiff18 = TimerDiff($hTimer)
Sleep(1)
$fDiff19 = TimerDiff($hTimer)
Sleep(1)
$fDiff20 = TimerDiff($hTimer)
Sleep(1)
$fDiff21 = TimerDiff($hTimer)
MsgBox(0, "", $fDiff1 & " : " & _ ;
   $fDiff2 & " : " & _ ;
   $fDiff3 & " : " & _ ;
   $fDiff4 & " : " & _ ;
   $fDiff5 & " : " & _ ;
   $fDiff6 & " : " & _ ;
   $fDiff7 & " : " & _ ;
   $fDiff8 & " : " & _ ;
   $fDiff9 & " : " & _ ;
   $fDiff10 & " : " & _ ;
   $fDiff11 & " : " & _ ;
   $fDiff12 & " : " & _ ;
   $fDiff13 & " : " & _ ;
   $fDiff14 & " : " & _ ;
   $fDiff15 & " : " & _ ;
   $fDiff16 & " : " & _ ;
   $fDiff17 & " : " & _ ;
   $fDiff18 & " : " & _ ;
   $fDiff19 & " : " & _ ;
   $fDiff20 & " : " & _ ;
   $fDiff21 & @CRLF & "Intervals." & @CRLF & _ ;
   $fDiff2 - $fDiff1 & " : " & _ ;
   $fDiff3 - $fDiff2 & " : " & _ ;
   $fDiff4 - $fDiff3 & " : " & _ ;
   $fDiff5 - $fDiff4 & " : " & _ ;
   $fDiff6 - $fDiff5 & " : " & _ ;
   $fDiff7 - $fDiff6 & " : " & _ ;
   $fDiff8 - $fDiff7 & " : " & _ ;
   $fDiff9 - $fDiff8 & " : " & _ ;
   $fDiff10 - $fDiff9 & " : " & _ ;
   $fDiff11 - $fDiff10 & " : " & _ ;
   $fDiff12 - $fDiff11 & " : " & _ ;
   $fDiff13 - $fDiff12 & " : " & _ ;
   $fDiff14 - $fDiff13 & " : " & _ ;
   $fDiff15 - $fDiff14 & " : " & _ ;
   $fDiff16 - $fDiff15 & " : " & _ ;
   $fDiff17 - $fDiff16 & " : " & _ ;
   $fDiff18 - $fDiff17 & " : " & _ ;
   $fDiff19 - $fDiff18 & " : " & _ ;
   $fDiff20 - $fDiff19 & " : " & _ ;
   $fDiff21 - $fDiff20)
Первый скрипт умышленно написан без цикла последовательными командами, чтобы не было сомнений о времени задержек на реализацию цикла.
Код:
$s = ""
$hTimer = TimerInit()
For $i = 1 To 25
   $n = Random(0, 10000000, 1)
   While $n > 0
      $n -= 1
   Wend
   $fDiff1 = TimerDiff($hTimer)
   Sleep(1)
   $fDiff2 = TimerDiff($hTimer)
   $s &= ($fDiff2 - $fDiff1) & @TAB & $fDiff1 & @TAB & $fDiff2 & @CRLF
Next
MsgBox(0, "", $s)
Второй скрипт генерирует случайные состояния этапа в периоде ожидания следующего прерывания (в первом скрипте все засыпания, кроме первого, происходят вскоре после выхода из сна, поэтому не видно разнообразие ситуаций).
Сообщение автоматически объединено:

Если всё же понадобится более высокая определённость в плане времени задержки, то могу предложить следующий компромисс между нагрузкой на процессор и нестабильностью времени.
Код:
$hTimer = TimerInit()
$flag = 0
$i = 0
While $flag = 0
   $i += 1
   If $i = 10 Then
      $i = 0
      If TimerDiff($hTimer) > 0.1 Then $flag = 1
   EndIf
WEnd
MsgBox(0, "", "Terminated in " & TimerDiff($hTimer) & " milliseconds.")
Увеличивая предельное значение 10 в условном операторе, можно уменьшить количество вызовов функции TimerDiff(), внеся при этом увеличение в неопределённость периода задержки.

Можно даже использовать совсем простой код.
Код:
$hTimer = TimerInit()
While TimerDiff($hTimer) < 0.1
WEnd
MsgBox(0, "", "Terminated in " & TimerDiff($hTimer) & " milliseconds.")
Но даже он при всей кажущейся эффективности выполняется чуть дольше, чем 100 микросекунд.

Впрочем, не удивлюсь, если окажется, что потребность в задержке 100 микросекунд оказалась ложным выводом из того, что якобы 1 миллисекунда это слишком много именно по причинам того, что в реальных тестах предполагаемая миллисекунда растягивалась порой на все 27 миллисекуд по изложенным выше (в основном) причинам. Тогда лучше использовать первое решение с увеличением двух предельных значений.
 
Последнее редактирование:

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
 

Oki

Продвинутый
Сообщения
452
Репутация
62
Это опять-таки не режим ожидания, а та же самая игра с таймером, не дающая никакой передышки процессору, причём нагружающая его затратными операциями, что не соответствует сформулированной топикстартером цели.

К тому же в посте по ссылке говорится, что на один лишь вызов той функции уходит 260 микросекунд. Вот этот скрипт и то за 7-12 микросекунд отрабатывает в попытке замахнуться всё на те же 100 наносекунд, которые как раз и являются шагом, с которым растёт отслеживаямая величина.
Код:
$hTimer = TimerInit()
While TimerDiff($hTimer) < 0.0001
WEnd
MsgBox(0, "", "Terminated in " & TimerDiff($hTimer) & " milliseconds.")

Сообщение автоматически объединено:

Кстати, хоть человек и пишет аж из 2008 года, у меня следующий скрипт с той функцией работает намного дольше.
Код:
$hTimer = TimerInit()
_HighPrecisionSleep(0.1)
MsgBox(0, "", "Terminated in " & TimerDiff($hTimer) & " milliseconds.")
; #FUNCTION#;===============================================================================
;
; Name...........: _HighPrecisionSleep()
; Description ...: Sleeps down to 0.1 microseconds
; Syntax.........: _HighPrecisionSleep( $iMicroSeconds, $hDll=False)
; Parameters ....:  $iMicroSeconds      - Amount of microseconds to sleep
;                  $hDll  - Can be supplied so the UDF doesn't have to re-open the dll all the time.
; Return values .: None
; Author ........: Andreas Karlsson (monoceres)
; Modified.......:
; Remarks .......: Even though this has high precision you need to take into consideration that it will take some time for autoit to call the function.
; Related .......:
; Link ..........;
; Example .......; No
;
;;==========================================================================================
Func _HighPrecisionSleep($iMicroSeconds,$hDll=False)
    Local $hStruct, $bLoaded
    If Not $hDll Then
        $hDll=DllOpen("ntdll.dll")
        $bLoaded=True
    EndIf
    $hStruct=DllStructCreate("int64 time;")
    DllStructSetData($hStruct,"time",-1*($iMicroSeconds*10))
    DllCall($hDll,"dword","ZwDelayExecution","int",0,"ptr",DllStructGetPtr($hStruct))
    If $bLoaded Then DllClose($hDll)
EndFunc
Обычно счёт идёт на миллисекунды!
Сообщение автоматически объединено:

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

Oki

Продвинутый
Сообщения
452
Репутация
62
Очень плохая идея.
Очень плохая идея подавать жалобы на тех, кто хотя бы думает, какой вопрос формулирует, а не несёт чушь, вроде той, которая в теме "Операции со строками, зачем это все?"
 

Alecsis

Осваивающий
Сообщения
101
Репутация
41
точность в 100 наносекунд существует только в нереализованных фантазиях, столкнувшихся с буднями технических трудностей
Лучше и не скажешь! Даже если эти фантазии и реализуемы, то однозначно не в рамках AutoIt, к-рый под такое изначально «не заточен».Тут разве что Ассемблер в помощь, и то сомнительно…
PS Вроде тема не закрыта, т.о. добавляю свой предпраздничный стопарик: :acute:
 
Автор
V

VadimKHL

Новичок
Сообщения
155
Репутация
0
Я просто не представляю проекта где нужна задержка но 1 тысячная секунды
Это логгер. Типа осциллографа. Данные передаются каждые 100 мкс. Поэтому 1 мс много, а без задержки тоже не правильно. Процессы как я понимаю должны "отдыхать".
Сообщение автоматически объединено:

Понял, тогда оставлю цикл без слипа. Вариантов получается что нет.
 
Последнее редактирование:

All2khoff

Продвинутый
Сообщения
352
Репутация
65
Ну как вариант записывать данные в массив, а затем уже работать с пакетом.
 
Сообщения
142
Репутация
-3
Понял, тогда оставлю цикл без слипа.
Sleep - это кувалда, кувалды в создании мозго осциллографа не п рименяются. Варианта два: искать причину жора или менять инструммент (ассемблер брать).
 
Последнее редактирование:
Верх