Comments 25
несколько месяцев программное обеспечение плохо работало по непонятной причине.
То есть вы вместо нормальной функциональности использовали недокументированный побочный эффект, а теперь удивляетесь что «внезапно» все сломалось?
This function affects a global Windows setting. Windows uses the lowest value (that is, highest resolution) requested by any process.
docs.microsoft.com/en-us/windows/win32/api/timeapi/nf-timeapi-timebeginperiod
Windows uses the lowest value (that is, highest resolution) requested by any process
Использует наименьшее значение — для какого процесса? До текущих изменений это следовало читать как «Windows использует для любого процесса наименьшее значение...», а теперь следует читать как «Windows использует для вызвавшего timeBeginPeriod процесса наименьшее значение...».
Недостаточная точность формулировок порождает разные трактования и ошибки типа «в главном процессе повысили точность, рассчитывали, что повысится и в дочерних, проверили — работает. Ой, перестало!» вполне возможны.
This function affects a global Windows setting.
В целом читается однозначно: используется меньшее, влияет на всю систему.
Претензия о том, что кто-то там что-то недокументированное использовал и поэтому заслуженно страдает — бред.
Кроме того, если принять Вашу точку зрения, что
читается однозначно: используется меньшее, влияет на всю систему
тогда получается, что это неверно документированное поведение, поскольку теперь не влияет на всю систему.
неверно документированное
Это да. Но она не менялось. Так что она либо была неправльная, либо сейчас неправильная. Обвинение разработчикам софта всё равно мимо.
В идеале при вызове Sleep(1) процессор переходит в спящий режим.
Вот оторвать бы руки тем, кто так пишет.
Sleep() это не "отправь процессор в сон", а "текущий поток (thread) хочет подождать". То есть Sleep() передаёт управление ОС и уже она решает, что там дальше делать. В большинстве случаев — квоту исполнения на текущем ядре просто получит другой поток (возможно даже этого же процесса). А отправка какого-либо ядра процессора в энергосберегающий режим — происходит только когда пул задач полностью исчерпан. И это (отправка в сон) совсем не подразумевается командой Sleep().
(Почитал про историю HLT, оказывается она действительно была в 8086, но включаемый ей режим пониженного энергопотребления появился только в 80486 DX4)
В том виде как сейчас — не было. Но в предыдущем комментарии ошибка в другом — хотя и многопоточных приложений тогда еще не было, то засыпал именно процесс, а не процессор.
Существовала программа waterfall.exe, после её запуска Pentium-166 становился ощутимо холоднее — в Windows 95 в простое крутился пустой цикл NOP, из-за чего процессор мог перегреваться, а waterfall ЕМНИП как раз выполняла HLT.
В том же Linux и сейчас есть всякие таблицы совместимости, которые могут отключить какую-то новую технологию на конкретном железе, потому что известно, что она на нём на самом деле не работает, несмотря на документацию.
Кстати, который раз убеждаюсь, что русскую раскладку клавиатуры таки наши люди делали — искал в тексте по Вашей ссылке NOP, набрал в русской раскладке ТЩЗ — ну так и есть, ТаЩаЗ.
А как это устроено в линуксах?
В Windows реализован костыль, чтобы бесконечный цикл с Sleep(1) жрал меньше электроэнергии ценой введения неявного поведения «мы знаем лучше, чем программист, сколько его Sleep должен длиться». Подобные циклы встречаются не очень часто (как верно замечено в статье). А если уж встречаются, то скорее всего программиста вполне устраивало повышенное энергопотребление (например, он воспроизводит 60fps анимацию).
Кстати, разработчикам Windows достаточно было бы сделать влияние настройки разрешения системного таймера локальным. То есть реальный системный таймер гонять на частоте наибольшего общего делителя от всех запрошенных разрешений, а доставлять реальные сигналы пробуждения потокам округляя их время пробуждения исходя из их настроек (то есть Sleep(N) транслируется в Sleep((N + 1) / РазрешениеТаймера * РазрешениеТаймера), где все операции целочисленные, а разрешение таймера хранится отдельно для каждого процесса, исходя из его обращений к функции изменения разрешения таймера). Тогда бы никаких глюков не было. Кроме того, что «ускорители таймера» перестали бы влиять на другие программы (а их задача как раз в том, чтобы чинить программы, которые ломаются от слишком медленного таймера). Однако изменение описанное в статье точно также их ломает, так что не вижу причин, почему нельзя всё было сделать по-нормальному.
Добавьте в пост ссылку на hacker news https://news.ycombinator.com/item?id=24684813
Системный таймер в Windows: большое изменение