Пропускаемый контекст: У меня есть цикл моделирования (с использованием фиксированного обновления, но с переменным шаблоном), который создает юридические лица классов, которые генерируются на лету в соответствии с пользовательским вводом и / или конфигурациями файлов из базы данных миллионов компонентов (из шаблон изменения состояния контейнера).
Я внедрил систему, которая автомагически…выводит (какая-то логическая ячейка / математика, имя которой я не знаю) и применяет необходимые компоненты всякий раз, когда пользовательский ввод / конфигурации игнорирует тот факт, что один из их вариантов требует дополнительных компонентов.
Как так? Многие из компонентов являются сложными формулами или нечеткой логикой (гейтами?) Или другими сложными научными рассуждениями, закодированными таким образом, чтобы они могли управлять структурой моего моделирования, его объектами, его средой, поэтому иногда один компонент опирается на другой, и мне нужно алгоритм / система дедукции, чтобы можно было передать эту зависимость конструктору классов.
Я использовал максимальную детализацию в том, как решил хранить эти «кусочки знаний», потому что я действительно не могу тратить впустую память, учитывая размеры и интенсивность вычислений моделирования и количество отдельных экземпляров, но сейчас я работаю над проблемой одному экземпляру нужны тысячи, иногда десятки тысяч компонентов, и мне нужно, чтобы «карта создания» экземпляра была сохранена и все еще привязана как закрытый член, чтобы я мог: 1-й — знать, куда мои выводы приводят конструктор экземпляров и, возможно, уметь использовать памятку для сокращения времени сборки; 2-й — внедрить внесение изменений в живой экземпляр во время симуляции¹.
Что мне нужно: Мне нужно возможно бесконечное или хотя бы очень длинное
битовая маска, так что я могу повторить создание быстрее и дать финальный
дерево компонентов моих динамически сконструированных объектов, записанных на будущее
использовать.Возможные подходы, о которых я понятия не имею, сработают: 1-й — вручную
и последовательно сохранять значения для битовых флагов в каждой ячейке RAM,
используя вафлю RAM в качестве моей бит-маски. 2-й — Разбить карту на
меньшие битовые маски известного размера (трудно, потому что конечное число
Компоненты неизвестны, пока создание не будет сделано и развязка
дедукция — это то, что даже невозможно без
рефакторинг всей системы). 3-й — выяснить способ сделать
бесконечная битовая маска, или использовать какую-то библиотеку, которая реализовала действительно
длинное целое число (5.12e + 11 или больше).
Мой код написан на C ++, мои ядра рендеринга и вычислений — Vulkan.
Мой объективный вопрос:
Как мне реализовать произвольно длинную битовую маску, которая эффективно использует память и вычисления?
Если мне разрешен бонусный вопрос, что такое большинство эффективный способ реализовать такую битовую маску, если у меня нет архитектурных (программных и аппаратных) ограничений?
¹ Я не могу просматривать дерево объекта во время симуляции, и я также не могу позволить себе приостановить симуляцию и подождать, пока просмотр будет сделан, прежде чем вводить модификацию, мне нужно знать и иметь возможность вносить произвольные изменения в произвольный кадр симуляции как заранее запланированным способом, так и в режиме реального времени.
Каков наиболее эффективный способ реализовать такую битовую маску?
Положил std::vector<bool>
там и профиль. Если / когда вы обнаружите, что тратите значительное время на работу с этим вектором, читайте дальше.
Нет наиболее эффективного способа, все зависит от того, что именно ваш код делает с этими битами.
Один из стандартных подходов — хранить непрерывный вектор целых чисел и рассматривать их как вектор битов. Например, std::vector<bool>
в Windows используются 32-битные значения, по 32 в каждом.
Однако API-интерфейс std :: vector слишком общий. Если ваш вектор имеет большинство 0 или большинство 1, вы сможете выполнить много операций (получить значение, найти первый / следующий / предыдущий 0/1) намного быстрее, чем std::vector<bool>
делает.
Также, в зависимости от ваших шаблонов доступа, вам могут потребоваться элементы меньшего или большего размера. Если вы решите использовать большие типы SIMD, т.е. __m128i
или же __m256i
не забывайте о выравнивании для них.
Других решений пока нет …