Вы используете устаревший браузер. Этот и другие сайты могут отображаться в нем неправильно. Необходимо обновить браузер или попробовать использовать другой.
Всем привет!
Подскажите пожалуйста, как можно делать задержки, допустим 100 мкс или другие подобные?
Проблем в том, что цикл без задержки сильно грузит ЦП, а Sleep меньше 1 мс низя((((
В реальности даже задержка на миллисекунду проблематична, поскольку пробуждение процесса из сна происходит за счёт синхронных прерываний от системных часов, периодичность которых куда менее часта, чем 1000 раз в секунду. Обычной частотой таких прерываний является величина 64 Гц, тогда интервал между такими прерываниями установлен в 15,625 миллисекунд, в результате чего инструкция засыпания на одну миллисекунду фактически может выполняться случайное время от одной миллисекунды до 16,625. Учитывая же тот факт, что в AutoIt вообще реально воспринимаемый параметр функции Sleep() не может быть меньшим 10, время выполнения инструкции Sleep(1) оказывается случайным в промежутке от 10 до 25,625 миллисекунд.
Процессор больше всего нагружает не беспрерывное выполнение, а какая-то конкретная требовательная к ресурсам инструкция. Можно разбавить её нетребовательными к ресурсам инструкциями, которые растрачивают время. Например, пустым циклом повторений, которые на уровне процессора будут лишь инкрементировать счётчик и сверять его значение с конечным. Поскольку сформулированные в стартовом посте цели не предполагают выполнение в течение заданного времени, не столь важна длительность этой задержки (она может в такой реализации зависеть от мощности компьютера и его загруженности другими задачами).
Сообщение автоматически объединено:
Два следующих скрипта демонстрируют непедантичность времени задержки в результате применения функции Sleep().
Второй скрипт генерирует случайные состояния этапа в периоде ожидания следующего прерывания (в первом скрипте все засыпания, кроме первого, происходят вскоре после выхода из сна, поэтому не видно разнообразие ситуаций).
Сообщение автоматически объединено:
Если всё же понадобится более высокая определённость в плане времени задержки, то могу предложить следующий компромисс между нагрузкой на процессор и нестабильностью времени.
Код:
$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 миллисекуд по изложенным выше (в основном) причинам. Тогда лучше использовать первое решение с увеличением двух предельных значений.
My god I was surprised when I found this function, it's frickin' awesome. It allows you to sleep down to 100 nanoseconds! UDF: ; #FUNCTION#;=============================================================================== ; ; Name...........: _HighPrecisionSleep() ; Description ...: Sleeps down to ...
My god I was surprised when I found this function, it's frickin' awesome. It allows you to sleep down to 100 nanoseconds! UDF: ; #FUNCTION#;=============================================================================== ; ; Name...........: _HighPrecisionSleep() ; Description ...: Sleeps down to ...
Это опять-таки не режим ожидания, а та же самая игра с таймером, не дающая никакой передышки процессору, причём нагружающая его затратными операциями, что не соответствует сформулированной топикстартером цели.
К тому же в посте по ссылке говорится, что на один лишь вызов той функции уходит 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 наносекунд существует только в нереализованных фантазиях, столкнувшихся с буднями технических трудностей.
Очень плохая идея подавать жалобы на тех, кто хотя бы думает, какой вопрос формулирует, а не несёт чушь, вроде той, которая в теме "Операции со строками, зачем это все?"
Лучше и не скажешь! Даже если эти фантазии и реализуемы, то однозначно не в рамках AutoIt, к-рый под такое изначально «не заточен».Тут разве что Ассемблер в помощь, и то сомнительно…
PS Вроде тема не закрыта, т.о. добавляю свой предпраздничный стопарик:
Это логгер. Типа осциллографа. Данные передаются каждые 100 мкс. Поэтому 1 мс много, а без задержки тоже не правильно. Процессы как я понимаю должны "отдыхать".
Сообщение автоматически объединено:
Понял, тогда оставлю цикл без слипа. Вариантов получается что нет.
Sleep - это кувалда, кувалды в создании мозго осциллографа не п рименяются. Варианта два: искать причину жора или менять инструммент (ассемблер брать).