Есть ли вектор, который может обрабатывать целые числа нестандартных битов? - PullRequest
4 голосов
/ 05 сентября 2011

Я ищу что-то похожее на вектор STL, но могу обрабатывать целые числа, например, 12, 16, 20, 24, 32 и 40 бит. 16-битные и 32-битные случаи прекрасно обрабатываются vector<uint16_t> и vector<uint32_t>, но я не смог найти никакого способа справиться с другими. Обратите внимание, что цель всего этого - сэкономить память и полосу пропускания, поэтому заполнение не вариант.

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

vector<bool> и dynamic_bitset могут создавать битовые поля, но они ограничены 1-битными целыми числами. Кто-нибудь знает что-то еще там?

1 Ответ

4 голосов
/ 05 сентября 2011

В STL их нет.

Я понимаю, что вы беспокоитесь о производительности, и особенно о памяти.Однако чтение без выравнивания (требующее сдвига битов) может быть медленнее, чем обычное (на границах байтов), поэтому я бы рекомендовал сохранять целые байты.Это означает:

  • 12 бит, 16 бит: uint16_t
  • 20 бит, 24 бита: либо 3 uint8_t, либо 1 uint32_t (скорость компромисса / память)
  • 32 бита: uint32_t
  • 40 бит: 5 uint8_t, 3 uint16_t или 1 uint64_t

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

boost::variant<
  std::vector<uint16_t>,
  std::vector<uint32_t>,
  std::vector<uint64_t>
>

Это позволит вам выбрать точное значение vector, которое будет использоваться во время выполнения, на основе количества необходимых вам байтов.для хранения.

Если вы хотите сэкономить как можно больше, то вам просто нужно добавить std::vector<uint8_t> в список.Но я бы воздержался от этого и, возможно, только "упаковал" 40-битный регистр (в uint16_t), так как другие никогда не тратят много памяти в любом случае ... и я, вероятно, хотел бы проверить обе альтернативы.

Примечание: вы также можете настроить использование векторной памяти, проверив, что capacity не превышает size слишком сильно.

...