Ukrainskiy
@Ukrainskiy

Самый эффективный способ поиска последовательности нулевых байт?

Нужно найти последовательность нулевых байт определенной длины, memchr нули не ищет, пробовал сделать дополнительный буфер с нулями и искать его с помощью memmem, работает быстро, но не уверен, что это адекватный способ и не хотелось бы выделять под это доп. память. Какие другие способы есть?
  • Вопрос задан
  • 131 просмотр
Пригласить эксперта
Ответы на вопрос 1
wataru
@wataru
Разработчик на С++, экс-олимпиадник.
Самый эффективный способ - использовать SIMD инструкции (какой-нибудь _mm256_cmpeq_epi8 и хитрую битовую арифметику вроде _mm256_movemask_epi8 и подобных над результатом).

Надо считать длину последовательности из нулей в начале и в конце блока и помнить длину последовательности заканчивающейся в конце предыдущего блока и продолжать ее в текущий блок.

Если вы ищите короткую последовательность, то еще нужно прверить, что в текущем болке она встречается. Например, чтобы проверить, что в битовой маске М есть последовательность из 5 бит, можно проверить, что (M & M >> 1) && ((M & M >> 1) >> 2) & M >> 4 имеет ненулевые биты. Достаточно log k сдвигов и битовых И для поиска последовательности из K ненулевых бит.

Но вряд ли вы будете с этим возиться. Следующий вариант - эмулировать SIMD руками в int64. Читайте из памяти по 8 байт (через memcpy в int64) и там уже проверяйте через LSB/MSB сколько нулевых байт на конце, в начале. Чуть сложнее, если вам надо искать последовательность короче восьми байт. Тогда надо еще отдельно проверить через битовые сдвиги, есть ли она внутри блока из 8 байт.

Дальше, есть какой-то ненулевой шанс, что memmem именно вариант выше и реализует, но это вряд ли. Я думаю ваш случай достаточно частен и ручная реализация будет быстрее.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы