Вкладчики в задержку звука

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

Если предположить, что аналоговая схема не вносит значительного вклада, то основными поверхностными факторами задержки звука являются следующие:

  • Заявление
  • Общее количество буферов в конвейере
  • Размер каждого буфера, в кадрах
  • Дополнительная задержка после процессора приложения, например, от DSP.

Каким бы точным ни был приведенный выше список участников, он также вводит в заблуждение. Причина в том, что количество и размер буфера являются скорее следствием , чем причиной . Обычно случается так, что заданная схема буфера реализована и протестирована, но во время тестирования недогрузка или переполнение звука слышны как «щелчок» или «хлопок». Чтобы компенсировать это, разработчик системы увеличивает размер буфера или количество буферов. Это приводит к желаемому результату устранения опустошения или переполнения, но также имеет нежелательный побочный эффект увеличения задержки. Дополнительные сведения о размерах буферов см. в видеоролике Задержка звука: размеры буферов .

Лучший подход — понять причины недорасхода и перерасхода, а затем исправить их. Это устраняет слышимые артефакты и позволяет использовать еще меньшие или меньшие буферы и, таким образом, уменьшить задержку.

По нашему опыту, наиболее распространенными причинами недорасхода и перерасхода являются:

  • Linux CFS (полностью честный планировщик)
  • высокоприоритетные потоки с планированием SCHED_FIFO
  • инверсия приоритета
  • длинная задержка планирования
  • долго работающие обработчики прерываний
  • длительное время отключения прерывания
  • управление энергопотреблением
  • ядра безопасности

Linux CFS и планирование SCHED_FIFO

Linux CFS спроектирован таким образом, чтобы быть справедливым по отношению к конкурирующим рабочим нагрузкам, использующим общий ресурс ЦП. Эта справедливость представлена ​​параметром nice для каждого потока. Значение nice колеблется от -19 (наименее приятно или больше всего выделенного процессорного времени) до 20 (наиболее приятное или меньше всего выделенного процессорного времени). Как правило, все потоки с заданным значением nice получают примерно одинаковое время ЦП, а потоки с численно меньшим значением nice должны получать больше процессорного времени. Однако CFS является «справедливым» только при относительно длительных периодах наблюдения. В краткосрочных окнах наблюдения CFS может непредвиденным образом распределять ресурсы ЦП. Например, это может отвлечь ЦП от потока с численно низкой точностью на поток с численно высокой точностью. В случае со звуком это может привести к недополнению или переполнению.

Очевидное решение — избегать CFS для высокопроизводительных аудиопотоков. Начиная с Android 4.1, такие потоки теперь используют политику планирования SCHED_FIFO , а не политику планирования SCHED_NORMAL (также называемую SCHED_OTHER ), реализованную CFS.

SCHED_FIFO приоритеты

Хотя высокопроизводительные аудиопотоки теперь используют SCHED_FIFO , они по-прежнему восприимчивы к другим потокам SCHED_FIFO с более высоким приоритетом. Обычно это рабочие потоки ядра, но также может быть несколько пользовательских потоков без звука с политикой SCHED_FIFO . Доступные приоритеты SCHED_FIFO находятся в диапазоне от 1 до 99. Аудиопотоки работают с приоритетом 2 или 3. Это оставляет приоритет 1 доступным для потоков с более низким приоритетом и приоритетами от 4 до 99 для потоков с более высоким приоритетом. Мы рекомендуем вам использовать приоритет 1, когда это возможно, и зарезервировать приоритеты от 4 до 99 для тех потоков, которые гарантированно завершатся в течение ограниченного периода времени, выполняются с периодом короче, чем период аудиопотоков, и о которых известно, что они не мешают планированию. звуковых потоков.

Монотонное планирование по скорости

Дополнительные сведения о теории назначения фиксированных приоритетов см. в статье Википедии « Монотонное планирование по скорости » (RMS). Ключевым моментом является то, что фиксированные приоритеты должны назначаться строго на основе периода, а более высокие приоритеты должны назначаться потокам с более короткими периодами, а не на основе предполагаемой «важности». Непериодические потоки можно моделировать как периодические потоки, используя максимальную частоту выполнения и максимальное количество вычислений за выполнение. Если непериодический поток нельзя смоделировать как периодический поток (например, он может выполняться с неограниченной частотой или неограниченными вычислениями за выполнение), то ему не следует назначать фиксированный приоритет, поскольку это было бы несовместимо с планированием настоящих периодических потоков. .

Инверсия приоритета

Инверсия приоритета — это классический режим отказа систем реального времени, когда задача с более высоким приоритетом блокируется на неограниченное время, ожидая, пока задача с более низким приоритетом освободит ресурс, такой как (общее состояние, защищенное) мьютексом . См. статью « Как избежать инверсии приоритетов » для получения информации о методах ее устранения.

Задержка планирования

Задержка планирования — это время между моментом, когда поток становится готовым к выполнению, и моментом, когда результирующее переключение контекста завершается, так что поток фактически выполняется на ЦП. Чем короче задержка, тем лучше, и все, что превышает две миллисекунды, вызывает проблемы со звуком. Длительная задержка при планировании чаще всего возникает при смене режима, например при включении или выключении ЦП, переключении между ядром безопасности и обычным ядром, переключении из режима полной мощности в режим пониженного энергопотребления или регулировке тактовой частоты и напряжения ЦП. .

прерывания

Во многих конструкциях ЦП 0 обслуживает все внешние прерывания. Таким образом, обработчик длительных прерываний может задерживать другие прерывания, в частности прерывания завершения прямого доступа к памяти (DMA). Разрабатывайте обработчики прерываний так, чтобы они быстро завершали работу и откладывали длительную работу на поток (предпочтительно поток CFS или поток SCHED_FIFO с приоритетом 1).

Аналогично, отключение прерываний на ЦП 0 на длительный период приводит к тому же результату, что и обслуживание прерываний аудио задерживается. Длительное время отключения прерываний обычно происходит во время ожидания спин-блокировки ядра. Просмотрите эти спин-блокировки, чтобы убедиться, что они ограничены.

Мощность, производительность и терморегуляция

Управление питанием — это широкий термин, который охватывает усилия по мониторингу и снижению энергопотребления при оптимизации производительности. Управление температурным режимом и охлаждение компьютера похожи, но они направлены на измерение и контроль тепла, чтобы избежать повреждений из-за избыточного тепла. В ядре Linux регулятор ЦП отвечает за низкоуровневую политику, а пользовательский режим настраивает высокоуровневую политику. Используемые методы включают в себя:

  • динамическое масштабирование напряжения
  • динамическое масштабирование частоты
  • динамическое ядро, позволяющее
  • кластерная коммутация
  • стробирование мощности
  • горячее подключение (горячая замена)
  • различные режимы сна (остановка, остановка, бездействие, приостановка и т. д.)
  • миграция процессов
  • привязка к процессору

Некоторые операции управления могут привести к «остановке работы» или времени, в течение которого процессор приложения не выполняет никакой полезной работы. Эти остановки работы могут мешать звуку, поэтому такое управление должно быть разработано для приемлемого наихудшего случая остановки работы, когда звук активен. Конечно, когда тепловой разгон неизбежен, предотвращение необратимого повреждения важнее, чем звук!

Ядра безопасности

Ядро безопасности для управления цифровыми правами (DRM) может работать на тех же ядрах процессора приложения, что и ядра основной операционной системы и код приложения. Любое время, в течение которого операция ядра безопасности активна на ядре, фактически является остановкой обычной работы, которая обычно выполнялась бы на этом ядре. В частности, сюда могут входить аудиоработы. По своей природе внутреннее поведение ядра безопасности непостижимо для уровней более высокого уровня, поэтому любые аномалии производительности, вызванные ядром безопасности, особенно пагубны. Например, операции ядра безопасности обычно не отображаются в трассировках переключения контекста. Мы называем это «темным временем» — временем, которое истекает, но его нельзя наблюдать. Ядра безопасности должны быть рассчитаны на приемлемую остановку работы в худшем случае, когда звук активен.