Как эффективно искать необработанные байтовые данные для первого экземпляра заданного значения c DWORD в C#? - PullRequest
0 голосов
/ 07 апреля 2020

В C / C ++ вы можете сделать это O(n) с указателем на буфер и приведением к 32-битному типу данных, но в C# с учетом byte[] или IEnumerable<byte> и int32, как вы могли бы эффективно найти первая позиция DWORD в байтовом буфере, в идеале с использованием встроенных методов библиотеки?

Я не хочу рисковать небезопасным кодом, поэтому я могу, конечно, искать 4-элементный байтовый суббуфер. Но есть ли более удобный способ использовать мое значение поиска длиной 32 бита?

Тривиальная обработка (псевдо-i sh):

int Find(IEnumerable<byte> buf, int val)
{
 byte d = val & 0xff, c = (val >>8) & 0xff, b = (val >>16) & 0xff, a = (val>>24) & 0xff;
 for(int i=0;i<buf.Length - 3;++i)
 {
  if(buf[i] == d && buf[i+1] == c && buf[i+2] == b && buf[i+3] == a)
   return i
 }
 return -1;
}

Интересно, смогу ли я объединить все 4 побайтных проверки с одной 32-разрядной проверкой.

1 Ответ

0 голосов
/ 07 апреля 2020

интересно, могу ли я объединить все 4 байтовых проверки с одной 32-битной проверкой

Не без нарушения выравнивания. Вот некоторые опции, которые у вас есть:

  1. 32-битное сравнение в маске с первой частью значения для каждого из 4 возможных выравниваний (это будет тестирование 32, 24, 16, или 8 бит). После того, как вы добьетесь успеха, вам все равно придется проверить оставшиеся биты

  2. Сравнение SIMD с поиском первого байта (или самого уникального - я, конечно, не хотел бы ищите 0x00, так как будет более 0,5% ложных срабатываний) иглы в 16 или около того возможных соседних местах одновременно. После того, как вы получите совпадение, вам нужно также проверить три следующих байта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...