Проверка наличия нулевой битовой записи.

Тема в разделе "WASM.A&O", создана пользователем cppasm, 23 мар 2010.

  1. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Привет.
    Вот такая есть задачка, что дано:
    Есть массив битовых записей, объём большой (~10Mb).
    Размер одной записи 10бит для определённости, но лучше решать в общем виде (nbits).
    Записи идут подряд от старшего бита к младшему: aaaaaaaa aabbbbbb bbbbcccc ccccccdd dddddddd
    Известно что в этом массиве есть нулевые записи - т.е. записи, все биты в которых установлены в 0.
    Также известно что записей этих мало: < 1% от общего числа.
    Требуется скопировать исходный массив в другой, при этом найти все эти записи и определённым образом обработать.
    Задача в том как максимально оптимально их найти с учётом того что их мало.
    Производительность очень критична, памяти 10К - так что большие таблицы не предлагать.

    У меня пока идеи такие - выбрать размер блока таким образом, чтобы его размер в битах был кратен 8 и кратен nbits.
    Т.е. чтобы блок содержал целое число байт и целое число записей.
    После чего проверяем есть ли в нём нулевые записи.
    Если нету - просто копируем, если есть - ищем какая именно запись и обрабатываем.
    Вот вопрос в том как проверить наличие нулевых записей максимально быстро, не перебирая их все.
    Т.е. не получать положение записи, сколько их таких в блоке и т.д., а просто есть или нету.
    Вот на этом я застрял как-то.
    С выделением каждой записи и проверкой всё работает, но долго.
     
  2. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Примитивно, но возможно вполне годно: сделать побитовое and всем 5 двордам, если результат 0 -- то тестить есть ли нули, количество промахов возможно будет приемлимым..
     
  3. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    cppasm
    Эту задачку для какого процессора решать требуется? Вариантов пока я вижу два: грузить в регистры и делать test/jz или сдвигать и делать OR чтобы получить в одном бите признак запись 0/не 0. Но последний вариант может быть хорош только для записей малого размера и для SSE.
     
  4. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    Еще одна мысль:
    mov eax,[esi]
    mov ebx,[esi+4]
    mov ecx,[esi+8]
    mov edx,[esi+12]
    mov ebp,[esi+16]
    sub eax,40100401h
    sbb ebx,10040100h
    sbb ecx,04010040h
    sbb edx,01004010h
    sbb ebp,00401004h
    sbb eax,0
    xor eax,[esi]
    xor ebx,[esi+4]
    xor ecx,[esi+8]
    xor edx,[esi+12]
    xor ebp,[esi+16]
    and eax,40100401h
    and ebx,10040100h
    and ecx,04010040h
    and edx,01004010h
    and ebp,00401004h
    or eax,ebx
    or eax,ecx
    or eax,edx
    or eax,ebp
    xor eax,555555555h
    jnz exist_zero_field
     
  5. Ravager

    Ravager New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2008
    Сообщения:
    34
    Если nbits>=15, можно сначала искать нулевой байт через repne scasb, а потом анализировать его окрестности.
     
  6. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Процессор ARM. nbits<16 всегда.

    Для 5 байт сложенных по И слишком часто будут промахи.
    Black_mirror последний вариант интересный, разбираюсь пока как работает.
    Но получается в итоге что оно того не стоит.
    Примерно таким же количеством команд можно по маске выделить записи и проверить.