Реализация bitset следует использовать для максимальной эффективности?

В настоящее время я пытаюсь реализовать различные алгоритмы в компиляторе Just In Time (JIT). Многие алгоритмы работают на растровых картах, более известных как битовые наборы.

В C++ существуют различные способы реализации bitset. Как истинный разработчик C++, я бы предпочел использовать что-то из STL. Наиболее важным аспектом является производительность. Мне не обязательно нужен динамически изменяемый битовый набор.

как я вижу, есть три возможных варианта.

I. Одним из вариантов было бы использовать std::vector<bool>, который был оптимизирован для космоса. Это также означает, что данные не должны быть смежными в памяти. Думаю, это может снизить производительность. С другой стороны, наличие одного бита для каждого значения bool может улучшить скорость, так как это очень удобно для кэша.

II. Другой вариант-вместо этого использовать std::vector<char>. Это гарантирует, что данные непрерывны в памяти и легче получить доступ к отдельным элементам. Однако странно использовать этот параметр, поскольку он не предназначен для битового набора.

III. Третий вариант - использовать фактическое std::bitset. Тот факт, что он не динамически изменяется, не имеет значения.

что выбрать для максимальной производительности?

3 ответов


лучший способ - просто сравнить его, потому что каждая ситуация отличается.

Я бы не стал использовать std::vector<bool>. Я попробовал один раз, и представление было ужасным. Я мог бы улучшить производительность моего приложения, просто используя std::vector<char> вместо.

Я не сравниваю std::bitset С std::vector<char>, а если пространство не является проблемой, в вашем случае, я бы пошел на std::vector<char>. Он использует в 8 раз больше места, чем бит-Набор, но поскольку ему не нужно выполнять битовые операции для получения или установки данные, это должно быть быстрее.

конечно, если вам нужно хранить много данных в bitset / vector, тогда было бы полезно использовать bitset, потому что это поместилось бы в кэш процессора.

самый простой способ-использовать typedef и скрыть реализацию. И bitset, и vector поддерживают оператор [], поэтому должно быть легко переключать одну реализацию другой.


недавно я ответил на аналогичный вопрос на этом форуме. Я рекомендую мой библиотека BITSCAN. Я только что выпустил версию 1.0. BITSCAN специфически конструировано для быстрых деятельностей сканирования бита.

класс BitBoard обертывает ряд различных реализаций для типичных операций, таких как bsf, bsr или popcount для 64-разрядных слов (он же bitboards). Классы BitBoardN, BBIntrin и BBSentinel расширяют битовое сканирование на бит веревка. Немного строку в BITSCAN массив bitboards. Базовый класс-оболочка для битовой строки-BitBoardN. BBIntrin расширяет BitBoardN, используя встроенные компоненты компилятора Windows на 64 битбордах. BBIntrin сделан портативным к POSIX путем использование соотвествующих функций эквивалента asm.

Я использовал BITSCAN для реализации ряда эффективных решателей для NP комбинаторных задач в области графа. Обычно матрица смежности графа, а также множества вершин кодируются как бит строки и типичные вычисления выполняются с использованием битовых масок. Код для простых объектов bitencoded graph доступен в графика. Примеры использования BITSCAN и GRAPH также доступны.

сравнение между BITSCAN и типичными реализациями в STL (bitset) и BOOST (dynamic_bitset) можно найти здесь: http://blog.biicode.com/bitscan-efficiency-at-glance/


вас также может заинтересовать эта (несколько устаревшая) бумага: http://www.cs.up.ac.za/cs/vpieterse/pub/PieterseEtAl_SAICSIT2010.pdf