Представление потоков битов в потоке байтов

Я экспериментирую с некоторыми идеями, согласно которым алгоритмы должны работать с битами как с наименьшей единицей информации. Это модульное приложение, в котором пользователь может переупорядочивать части «конвейера», подобно конвейеру оболочки unix. Эти алгоритмы выполняют различные функции, такие как кадрирование, сжатие, распаковка, проверка и исправление ошибок; введение, обнаружение и удаление шума и т. д.

Так как они работают на битовом уровне, алгоритмы могут, например, принимать 5 битов на вход и выдавать 19 бит на выходе. Ввод и вывод редко бывают кратными байтам.

Работать с потоками битов в памяти и между потоками можно с помощью std::vector<bool>, но мне нужно извлекать и сохранять этот поток битов откуда-то и куда-то, и желательно, чтобы можно было выполнять настоящие конвейеры командной строки, например:

prog1 < bitsource.dat | prog2 -opts | prog3 -opts > bitsink.dat

Или даже:

prog1 | prog2 | ssh user@host /bin/sh -c "prog3 | prog4 > /dev/dsp"

Проблема заключается в том, как эффективно сериализовать эти биты, поскольку стандартные потоки (stdin и stdout) ориентированы на байты. Мне приходится обрабатывать ситуации, когда количество битов на входе и выходе не кратно байту.

В настоящее время у меня есть рабочее доказательство концепции, которое делает это, расширяя каждый бит до байта, который имеет значение 0x30 или 0x31 ("0" или "1"). Очевидно, что это увеличивает размер данных в восемь раз, потребляя в 8 раз больше места и полосы пропускания, чем необходимо. Я хотел бы, чтобы эти биты были упакованы более эффективно.

Одной из альтернатив, которые я рассматриваю, является протокол, который буферизует биты на выходе и создает блоки, состоящие из заголовка Length, за которым следуют ceiling(Length/8) байты данных. , очищая вывод при необходимости.

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


person Juliano    schedule 03.01.2011    source источник
comment
Конечно, это очень неэффективно? Действительно? Измерение времени может быть довольно хорошим, учитывая, насколько медленными являются некоторые системы ввода-вывода. Вы измерили это? Или вы про расширение 8х1 по размеру? Какую эффективность вы ищете?   -  person S.Lott    schedule 03.01.2011
comment
@S.Lott: Да, я говорю о восьмикратном увеличении размера. Пространство (хранение), пропускная способность (передача по сети) и эффективность процессора (преобразование во время ввода/вывода) являются проблемами, особенно пространство и пропускная способность. И восьмикратное увеличение редко остается незамеченным. Если все пойдет хорошо, это следует использовать для приложения реального времени. Я хотел бы сделать это хорошо сейчас, чем иметь узкое место, которое потребует переписать все позже.   -  person Juliano    schedule 03.01.2011
comment
Пожалуйста, обновите вопрос, чтобы сделать его совершенно ясным. Это ваш вопрос; вы можете улучшить его. Длинную цепочку комментариев сложно объединить в один четкий вопрос.   -  person S.Lott    schedule 03.01.2011
comment
@ С.Лотт: Готово. Немного прояснил.   -  person Juliano    schedule 03.01.2011


Ответы (1)


протокол, который буферизует биты на выходе и создает блоки, состоящие из заголовка Length, за которым следуют максимальные (длина/8) байты данных, очищая вывод при необходимости.

Это типично. На самом деле нет никаких альтернатив, которые были бы достаточно простыми.

Сериализация битов — как битов — встречается редко. Битовые индексы — это единственный пример, который приходит на ум.

Язык программирования Pascal кодирует все строки длиной, за которой следуют байты строки. Вы делаете то же самое, за исключением того, что это биты, а не байты.

Это похоже на «кодирование длин серий», где серии идентичных значений заменяются заголовком и байтами. Алгоритм PackBits, например, представляет собой простой RLE, который предоставляет заголовок и данные. Он работает на уровне байтов (а не на уровне битов), но, по сути, это тот же шаблон проектирования.

person S.Lott    schedule 03.01.2011
comment
Хотя это не тот ответ, который я искал (что-то стандартное или что-то, что кто-то уже придумал раньше), я пошел по этому пути, и в конце концов это сработало очень хорошо. Спасибо за ваш вклад. - person Juliano; 13.02.2011