Buffer underrun
Buffer underrun (алсо опустошение буфера, недогруз, буферный коллапс, анальная кара звукарей) — это феерическое состояние системы, при котором устройство, читающее данные из буфера, ВНЕЗАПНО обнаруживает, что читать-то и нечего, потому что тормознутый источник не успел туда эти самые данные положить. В результате девайс давится воздухом, процесс прерывается, а юзер получает порцию отборных лулзов в виде запоротой болванки, заикающегося звука, фризов на экране или синего экрана смерти.
В терминах этой вашей реальной жизни сабж можно сравнить с ситуацией, когда ты пьешь пиво через воронку: если твой собутыльник наливает жидкость медленнее, чем ты глотаешь, воронка пустеет, ты заглатываешь воздух, давишься, блюешь и портишь вечеринку. PROFIT!
Дела давно минувших дней[править]
Золотые времена[править]
Школота не помнит, но в конце 90-х и начале 00-х годов запись компакт-диска была сродни запуску шаттла. Процесс требовал максимальной концентрации, отключения всех фоновых программ, мыши, клавиатуры, кота и дыхания. Причина была проста: если ты начал прожигать диск, лазер не мог просто так остановиться, подождать, пока твой 1-ядерный Pentium 166 подгрузит следующую порцию порнухи с медленного жесткого диска, и продолжить.
Буфер резака (обычно от 1 до 8 мегабайт) был единственной прослойкой между непрерывным лазером и тормознутой шиной IDE. Как только ползунок Buffer Level в божественном Nero Burning ROM падал до 0 %, происходил ОН. Buffer underrun. Программа выдавала фатальную ошибку, лоток привода с мерзким щелчком выплевывал недописанный диск, и кусок пластика за 10 баксов мгновенно превращался в блестящую подставку для кофе (coaster).
Анонимус, пытавшийся записать 700 мегабайт свежего вареза, мог потерять до 5 болванок за 1 вечер, потому что мама решила позвонить по телефону и оборвала dial-up соединение, или антивирус Касперского решил именно в этот момент обновить свои базы, сожрав 100 % процессорного времени.
Технологическое спасение[править]
Ближе к 2001 году производители железа поняли, что так жить нельзя. Sanyo выкатила технологию BURN-Proof (Buffer Under RuN Proof), а другие подтянулись со своими аналогами: JustLink от Ricoh, Seamless Link от Philips, SafeBurn от Yamaha. Суть сводилась к тому, что привод научился ВНЕЗАПНО выключать лазер за 1 микросекунду до опустошения буфера, запоминать место остановки, ждать, пока буфер наполнится, и с ювелирной точностью (разрыв всего около 40 микрометров) возобновлять прожиг.
Сейчас повсеместно имеются в продаже приводы с поддержкой технологий BurnProof или JustLink... которые лишены подобных проблем.
Именно тогда форумы наполнились радостными воплями: Я могу играть в Quake 3, пока пишется диск! Это был эпический вин инженеров и смерть индустрии по производству подставок для кофе.
DMA vs PIO[править]
Но даже с защитой от андерранов, быдлокодеры из Microsoft иногда подкладывали свинью. Windows могла самовольно перевести жесткий диск или CD-ROM из режима DMA (Direct Memory Access), где устройства обменивались данными в обход процессора, в режим PIO (Programmed Input/Output), где каждый байт прокачивался через бедный CPU. В режиме PIO загрузка процессора улетала в небеса (до 100 %), система фризилась, мышка двигалась рывками, а буфер опустошался быстрее, чем школьник спускает карманные деньги. Лечилось это шаманством в Диспетчере устройств, удалением контроллера и перезагрузкой, после чего винда с умным видом находила Новое устройство и возвращала заветный DMA.
Аудиофилы[править]
Если в записи оптических дисков проблему решили аппаратно, то в сфере создания музыки сабж живет и здравствует даже в 2026 году, собирая свою кровавую жатву.
ASIO, задержки и треск[править]
Любой диджей, битмейкер или мамкин продюсер, скачавший паленую FL Studio или Ableton, рано или поздно сталкивается с ним. Ты вешаешь на мастер-канал 5 инстанций FabFilter, добавляешь 3 тяжеловесных патча из Kontakt 7, и ВНЕЗАПНО твой шедевр превращается в трещащую, пердящую какофонию. Это и есть buffer underrun в реальном времени.
Звуковая карта работает по принципу кольцевого буфера. DAW (Digital Audio Workstation) должна успеть просчитать все эффекты, плагины и синтезаторы, сложить это в буфер, откуда звуковая карта забирает готовые сэмплы на ЦАП (цифро-аналоговый преобразователь). Если процессор не успевает (не вытянул сложную математику ревербератора), звуковая карта вычерпывает буфер до дна и… воспроизводит либо тишину, либо повторяет последний кусок, что звучит как омерзительный цифровой треск, щелчки (clicks and pops) или пулеметная очередь.
I have buffer underruns if I don't set my projects buffer size at least at 512... Could I set my buffer size as low as 64 with the latest intel cpu?
Решение проблемы сводится к 2 путям, оба из которых полны страданий:
- Увеличить размер буфера. Делаешь буфер не 64 сэмпла, а 1024 или 2048. Процессору дается больше времени на просчет, треск исчезает. PROFIT? Как бы не так. Возникает огромная задержка (latency). Ты нажимаешь клавишу на MIDI-клавиатуре, а звук появляется через 50 миллисекунд. Играть вживую становится физически невозможно, мозг ломается от рассинхрона моторики и слуха.
- Уменьшить буфер и страдать. Играешь с минимальной задержкой, но каждый аккорд сопровождается треском, как будто ты жуешь пенопласт перед микрофоном.
DPC Latency[править]
Отдельная дисциплина Специальной Олимпиады — это поиск драйвера, который вызывает опустошение буфера на топовом железе. Ты купил Core i9, 64 гигабайта оперативки, звуковую карту Focusrite за over 9000 денег, поставил буфер на 512, а оно всё равно трещит!
Тут на сцену выходит утилита LatencyMon. Суть в том, что в архитектуре Windows (да и Linux тоже) драйверы общаются с процессором через прерывания (IRQs) и отложенные вызовы процедур (DPCs). Если какой-нибудь криво написанный драйвер Wi-Fi адаптера или видеокарты от NVIDIA захватит процессор слишком надолго и не отдаст управление, аудиодрайвер не успеет положить данные в буфер. Итог: buffer underrun на 24-ядерном монстре.
На форумах Gearspace и Reddit лежат 1000 тредов, где несчастные пользователи отключают Wi-Fi, Bluetooth, энергосбережение процессора (C-States), удаляют GeForce Experience, переводят схемы питания в High Performance, шаманят с таймерами (HPET) и IRQ приоритетами, лишь бы сбить этот проклятый DPC latency.
It was wdf01000.sys and some nvidia driver... Stuff like this just makes me want to stop use a computer altogether. The more advanced stuff gets the more things can go wrong.
ASIO4ALL vs Native Drivers[править]
Исторически виндовый аудиостек (DirectSound, WASAPI) был не приспособлен для работы с низкими задержками, пропуская звук через 100500 программных микшеров ОС. В ответ сумрачный тевтонский гений по имени Михаэль Типпах (Michael Tippach) написал ASIO4ALL — костыль поистине космических масштабов, который позволяет любой встроенной звуковухе (типа Realtek) работать в режиме ASIO (Audio Stream Input/Output), минуя системные микшеры.
Но костыль есть костыль. Использование ASIO4ALL часто приводит к тому, что FL Studio захватывает аудиоустройство монопольно, и ты не можешь параллельно посмотреть туториал на YouTube — браузеру просто некуда выводить звук, буферы заняты. А если попытаться запустить 2 программы с ASIO, система может выдать такой buffer underrun, от которого вылетят динамики вместе с барабанными перепонками.
Видео[править]
Сабж регулярно посещает и обывателей, далеких от IT и написания транс-музыки. Ты открываешь видео в 4K, интернет тупит, серая полоска предзагрузки в плеере останавливается, и красный ползунок воспроизведения настигает её. Буфер опустел. Экран замирает, появляется крутящееся колесико (или спиннер), и ты сидишь, медитируешь, ожидая, пока пакеты TCP/IP соизволят доползти от серверов до твоего провайдера.
В мире онлайн-трансляций (Twitch, Kick) buffer underrun ведет к пропуску кадров (dropped frames). У стримера не тянет битрейт или процессор не успевает кодировать поток в H264/NVENC. Плеер у зрителя недополучает кадры, буфер истощается, стрим заикается, зрители спамят в чат F, лагает, покорми хомяка в сервере.
Framebuffer в играх[править]
В 3D-графике роль буфера выполняет Framebuffer (буфер кадра), куда видеокарта рендерит картинку перед отправкой на монитор. Если GPU не успевает отрисовать кадр за отведенные 16.6 миллисекунд (для 60 Гц), монитор, работающий по классической схеме V-Sync, выведет старый кадр еще 1 раз. Технически это тоже опустошение (или, скорее, неготовность) буфера для вывода. Результат — мерзкий stuttering (микрофризы) и падение FPS с 60 до 30. Лечится это технологиями типа G-Sync и FreeSync, которые синхронизируют частоту обновления монитора с моментом готовности буфера кадра, не позволяя монитору требовать данные, когда они еще не срендерены.
Как возникает Buffer Underrun на уровне железа[править]
Чтобы понять всю глубину кроличьей норы, нужно спуститься на уровень машинных кодов и шин данных. Компьютер — это не монолитный мозг, а сборище тупых, но быстрых чипов, которые общаются друг с другом через прерывания.
Допустим, у нас есть процесс A (проигрыватель аудио), который генерирует данные со скоростью 44100 сэмплов в секунду (стандарт CD-Audio). И есть устройство B (аудиочип), которое эти данные пережевывает и выплевывает на колонки с той же скоростью.
Между ними находится участок оперативной памяти — кольцевой буфер (ring buffer). Процесс A выступает в роли Producer (производитель), записывая данные в начало буфера и двигая указатель записи (write pointer) вперед. Устройство B выступает в роли Consumer (потребитель), считывая данные и двигая указатель чтения (read pointer) вслед за указателем записи.
Кольцевой буфер конечен. Если указатель чтения догоняет указатель записи (то есть потребитель съел всё, что произвели, и уткнулся в пустоту) — это и есть Buffer Underrun. Потребитель орет: Где мои данные, сука?!, но процессор в этот момент был занят тем, что антивирус решил проверить скачанный кейген для того самого софта.
Противоположная ситуация — Buffer Overrun (или Overflow), когда производитель работает слишком быстро, буфер заполняется на 100 %, и указатель записи догоняет указатель чтения сзади, затирая еще не считанные данные (или система просто дропает новые данные, что приводит к потерям пакетов в сетях). ЧСХ, Buffer Overflow также является самым популярным вектором хакерских атак (переполнение буфера на стеке, затирание адреса возврата, выполнение шелл-кода и захват контроля над машиной).
Закон Парето для задержек[править]
Среди IT-шаманов известно, что 80 % проблем с опустошением буфера в современном мире вызваны 20 % кривых драйверов. В операционной системе Windows (в отличие от RTOS — операционных систем реального времени, используемых в авионике или кардиостимуляторах) нет жестких гарантий выполнения задачи за определенный квант времени.
Даже если ты выставишь приоритет аудио-потока на Realtime, ядро Windows всё равно может решить, что обработать прерывание от ACPI (подсистемы управления питанием), когда ты изменил яркость экрана на ноутбуке, важнее. Ядро ставит аудио на паузу на 2 миллисекунды. Если твой буфер рассчитан на 1 миллисекунду (около 44 сэмплов) — добро пожаловать в страну щелчков.
Как лечить[править]
За 3 десятилетия борьбы с сабжем человечество выработало ряд ритуалов. Большинство из них бессмысленны, но некоторые работают.
- Увеличение размера буфера. Самый тупой, логичный и надежный метод. Больше буфер — больше устойчивость к просадкам производительности. Минус — задержка. Если ты пишешь лайв или играешь в киберспорт, это не твой бро.
- Отключение Wi-Fi и Bluetooth адаптеров. Сетевые карты, особенно от Broadcom или дешевые USB-свистки, печально известны тем, что их драйверы монополизируют системную шину (PCIe) и DPC-очередь, сканируя эфир в поисках сетей каждые 10 секунд. Вырубаем их к чертям, и треск в колонках уходит.
- Отключение C-States и энергосбережения в BIOS. Процессор пытается экономить электричество и постоянно паркует ядра, снижает частоту, засыпает. Выход из состояния глубокого сна (C6/C7) занимает микросекунды, но этого достаточно, чтобы буфер звуковой карты обсох. Тру-музыканты отключают Intel SpeedStep, AMD Cool’n’Quiet и выкручивают всё на постоянные 100 % частоты.
- Latencymon. Запуск утилиты на 10 минут. Выявление файла ndis.sys (сеть), nvlddmkm.sys (видео драйвер NVIDIA), usbport.sys (USB контроллер), или wdf01000.sys (основа драйверов винды). Далее начинается гугление кодов ошибок, обновление BIOS материнской платы, перепрошивка контроллеров, снос системы, молитва, жертвоприношение системного блока Перуну.
- Переход на Mac. Благодаря CoreAudio и жесткому контролю Apple за железом и драйверами, Mac OS X традиционно лучше справляется с аудио низких задержек прямо из коробки. Опустошение буфера там тоже бывает, но для его достижения нужно постараться гораздо сильнее (например, открыть 100 тяжелых плагинов на MacBook с 8 Гб ОЗУ).
- Смена железа. Иногда проблема физически кроется в говенном USB-порту материнской платы, который делит одно прерывание с контроллером SATA. Втыкаешь звуковую карту в другой порт — и, о чудо, всё работает.
Stutter Edit[править]
То, что для инженеров является критической ошибкой, для креативного класса быстро стало фичей. Специфический звук опустошения буфера аудиокарты — это повторяющийся кусок сэмпла в несколько миллисекунд. Звучит как механическое, пулеметное заикание, зацикленное на одной ноте (иногда это называют эффектом Макса Хэдрума в честь популярного в 80-е глючного телеперсонажа).
Электронные музыканты (в жанрах Glitch, IDM, Dubstep, Breakcore) послушали, как звучит зависшая Windows с синим экраном смерти под музыку, и сказали: А это звучит охуенно!. В итоге появились целые VST-плагины (например, знаменитый Stutter Edit от iZotope, разработанный музыкантом BT, или dBlue Glitch), которые ИСКУССТВЕННО симулируют buffer underrun, нарезая входящий звук на куски по 16, 32, 64 ноты и зацикливая их с разной скоростью.
То есть индустрия потратила миллиарды долларов на разработку сверхбыстрых процессоров, шин PCIe, протоколов ASIO и CoreAudio, чтобы полностью избавиться от буферных артефактов… только для того, чтобы музыканты покупали за 199 баксов плагин, который добавляет эти артефакты обратно в трек. Логово абсурда.