Обновить

Комментарии 15

Так нужна-то автору была очередь или кольцевой буфер? Какой смысл обсуждать производительность, если это разные вещи по смыслу?

Нужна была FIFO очередь аудиоданных. Изначальна она работала на std::deque, но затем я заменил ее на кольцевой буфер boost::circular_buffer - естесственный выбор для аудио, тем более что ALSA сама использует кольцевой буфер. Семантика не изменилась, поэтому сравнение корректно; неожиданно, кольцевой буфер оказался значительно медленнее.

Как же семантика не изменилась, если кольцевой буфер закольцован? Его назначение - вытеснять старые блоки.

Закольцованность - это организация памяти, а вытеснение - лишь политика при переполнении. У меня запись шла только при наличии места, поэтому буфер оставался обычно ограниченной FIFO очередью.

Ну так и получили оверхед на поддержке ненужного вам вытеснения.

просто boost::circular_buffer это плохой буфер, полно более хороших реализаций

Похоже на то - по крайней мере в моем сценарии boost::circular_buffer значительно проиграл std::deque. Если можете посоветовать конкретную реализацию, было бы интересно сравнить.

Кольцевой буфер (непотокобезопасный, с фиксированным размером) довольно простая структура, под вашу задачу пилится за 2-3 часа в 200-400 строк кода. Плюс самописной реализации в том, что вы можете подогнать ее под ваши требования и выжать максимум.

Смысл своего велосипеда есть только если тебе нужны специфичные гарантии по latency, которых нет в стд

Странно, программируя на C++, так бояться велосипедов. Структура в пару сотен строк с примитивной логикой и уже тащить стороннюю библиотеку? Если так в себе не уверены, зачем вообще прогать на плюсах, есть питон, где все из коробки. Структуры STL носят универсальный характер и обязаны давать кучу гарантий из-за чего не могут быть максимально производительны для конкретной задачи, могут быть приемлимы.

Автор пилит аудиоочередь, где оптимальным был бы кольцевой буфер, вместо deque, так как кеш-френдли, выравнивание по 64 байт для avx512 и т.д. Но его не устроила усложненная реализация boost, которая опять же универсальна.

жиза жизовая) в поисках тонкого места иногда можно набрести на вообще неожиданные места

а еще во многих языках програмирования некторые веши оптимизированы асм-вставками под популярные процессоры и потому на реальных тестах может оказатся что "не оптимальный" алгоритм работы на самом деле оптимальнее чем "сделаный правильно"

Да, живой код регулярно ломает красивые теории :)

Поэтому профилировщик всегда должен быть открыт раньше, чем документация по структурам данных

Кольцевой буфер на то и кольцевой, что при чтении блоками всегда будет проблема перехода через границу массива)

А кто им мешал сделать это через две быстрые операции: чтение до конца массива и чтение от начала и до нужного индекса? Там же, наверное, не побайтное чтение?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации