Нужен эффективный бинарный протокол для С\С++ для сериализации данных (с точки зрения объёма сериализованных данных)
Есть задача передать фиксированный объём данных по беспроводной сети. Узким местом системы является объём трафика, скорость сериализации-десериализации второстепенна. Нужен бинарный протокол, который во время сериализаций сгенерируем самый маленький пакет. Из бинарных протоколов у меня большой опыт работы с Google protobuf, но для этой задачи он генерирует очень большие пакеты. Хотелось-бы что-то похожее на него, но что бы ему можно было задать размеры данных в битах. Например, у меня много переменных, максимальное значение которых не превысит 16ти. Протобуф будет выделять под них по 1 байту, хотя можно уложиться в 4 бита. Есть что-то эффективней протобуфа?
Условия у моей задачи следующие:
Структура передаваемых данных известна заранее. Т.е. на этапе компиляции мы точно знаем какие пакеты будем передавать.
Каждый тип пакета должен быть фиксированной длинны, которая выбирается на этапе компиляции. Т.е. если у нас есть 3 типа пакета, то на этапе компиляции мы должны знать максимальный размер всех трёх типов. Если у какого-то типа пакет, после сериализации, может занимать от 12 до 16 байте, то при получении 12 байт мне всё равно придётся добивать его до 16 и передавать 16 байт.
Очень желательно (но не обязательно) чтобы библиотека была хедер-онли. Часть работы будет производиться на микроконтроллере.
upd: Если немного переформулировать вопрос, то нужен протокол, который сгенерирует самый маленький бинарный пакет в наихудшем случае. В обсуждении с user7860670 я объяснил почему любой алгоритм сжатия не подходит (из-за второго ограничения). Все отдельные поля объектов были сокращены еще до сериализации (т.е. если значения, которые могут быть от 10 до 16 приводятся к 0-6 и переводятся в 3 битовый размер. Числа с плавающей запятой нормализуются и переводятся в intxx_t и т.д.). Всё что мне нужно, это эффективный бинарный протокол. Хотя @Mike в комментариях уже подсказал решение, которое меня устраивает.
Ответы (1 шт):
Как учит нас товарищ Шеннон, все зависит от вероятностного распределения входных данных и от их природы, без детального изучения природы каждого параметра что-то ответить сложно.
Алгоритмы сжатия, которые тут настойчиво предлагают, как раз и занимаются тем, что автоматически пытаются изучить природу входного сигнала с тем, чтобы пересылать его максимально эффективно.
Подумайте например над тем, чтобы передавать не саму величину, а дельту от предыдущего состояния.
Очевидно, что требования "длина пакета априори известна и фиксирована" и "хочу все сжать максимально" - являются противоречивыми, реализовать можно что-то одно - сжатие приводит к пакетам переменной длины.
Предложение
оценить потребные скорости (длина фрейма в байтах) и задержки (время между фреймами). Через сколько посланных фреймов данных произойдет реальное устаривание? Действительно ли пропускная способность выбранного вами канала укладывается в эти рамки? Действительно ли сюда подходит TDM? Возможно, что вы изначально посадили себя в лужу, выбрав не те технологии.
Подробно расписать, какой природы данные вы пересылаете. Двоичное состояние датчика, аналоговый сигнал и так далее. Если речь идет об аналоговом сигнале, нужно оценить его спектр. Если о двоичном - частоту дискретизации и вероятности появления каждого нового состояния.