Windows: Сон(0.5)

Как многие наверное знают, в функции WinAPI Спать передается количество миллисекунд, на какое время мы хотим заснуть.

Поэтому минимум, что мы можем запросить — это заснуть на 1 миллисекунду.

Но что, если мы хотим спать еще меньше? Кому интересно, как это сделать в картинках, добро пожаловать под кат. Во-первых, позвольте мне напомнить вам, что Windows (как и любая система, не работающая в режиме реального времени) не гарантирует, что поток (некоторые называют его потоком) будет спать ровно запрошенное время.

Начиная с Vista, логика ОС проста.

Потоку на выполнение выделяется определенный интервал времени (да-да, те самые 20 мс, о которых все слышали во времена 2000/XP и до сих пор слышат на серверных осях).

И Windows перепланирует потоки (останавливает одни потоки, запускает другие) только после истечения этого кванта.

Те.

если квант в ОС 20 мс (по умолчанию в XP такое значение было, например), то даже если мы запросили Сон(1) тогда в худшем случае управление к нам вернется через те же 20 мс.

Для управления этим квантом времени существуют мультимедийные функции, в частности времябегинпериод/времяконецпериод .

Во-вторых, сделаю небольшое отступление, зачем может потребоваться такая точность.

Microsoft утверждает, что такая точность нужна только мультимедийным приложениям.

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

У меня была потребность в другой области.

У нас был декомпрессор потока H264. И это было на ffmpeg. И у него был синхронный интерфейс (Frame* decompressor.Decompress(Frame* compressedFrame)).

И всё было хорошо, пока не добавили распаковку чипов Intel в процессорах.

В связи с тем, что я не помню никаких причин, мне пришлось работать с ним не через родной Intel Media SDK, а через интерфейс DXVA2. И это асинхронно.

Поэтому мне пришлось работать следующим образом:

  • Копирование данных в видеопамять
  • Делаем Sleep, чтобы кадр успел расслабиться
  • Спрашиваем, завершилась ли распаковка, и если да, то берем распакованный кадр из видеопамяти
Проблема оказалась во втором пункте.

По данным GPUView, кадры распаковывались за 50–200 микросекунд. Если вы поставите Сон(1) то на core i5 можно сжать максимум 1000*4*(ядер)=4000 кадров в секунду.

Если предположить, что обычный fps равен 25, то это означает, что одновременно распаковывать нужно только 40*4=160 видеопотоков.

А цель была дойти до 200. Собственно, было 2 варианта: либо перевести всё на асинхронную работу аппаратным декомпрессором, либо уменьшить время Sleep.

Первые измерения

Чтобы примерно оценить текущий квант времени потока, напишем простую программу:
   

void test() {

Теги: #winapi #native api #C++ #api #разработка для Windows
Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.