Реализация 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