Сканирование бит

Тема в разделе "WASM.A&O", создана пользователем persicum, 2 апр 2008.

  1. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Присматриваюсь к команде
    bsf ebx,eax

    Нужно получить поочередно все ненулевые биты в EAX...
    Так что, после каждой bsf сбрасывать бит в eax под номером ebx вручную чтоли отдельной командой?
     
  2. Joes

    Joes New Member

    Публикаций:
    0
    Регистрация:
    5 янв 2008
    Сообщения:
    98
    Что то типа:

    В eax - значение которое проверяешь.
    Код (Text):
    1. xor ecx, ecx
    2. t:
    3. mov edx, 1
    4. shl edx, cl
    5. and edx, eax
    6. jz nobit
    7. ... тут знаем что бит который в cl стоит
    8. nobit:
    9. inc ecx
    10. cmp ecx, 32
    11. jb t
     
  3. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    persicum
    Можно так
    Код (Text):
    1.    xor ecx,ecx
    2.    mov cl,32
    3. a1: shl eax,1
    4.       jnc nobit
    5. ... тут знаем, что бит который в cl стоит
    6. nobit: loop a1
    Здесь решалась похожая задача
     
  4. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Не господа-чуваки, так дело не пойдет.
    Известно, что ненулевых бит в eax мало, а то и вообще нет...
    32 раза вертеть запаришься...

    вот код который у меня ща работает.

    Что бы хотелось улучшить:
    либо отказаться от btc вообще,
    либо заменить jmp на условный, чтобы не делать последний холостой оборот,
    когда битов уже заведомо нету оставшихся. Не приложу ума, как это можно сделать, иба btc флаг нуля не трогает, вообще убогие команды мля!

    Код (Text):
    1. @loop:                      
    2.    bsf ebx,eax        
    3.    jz @quit // не нашла          
    4.       --- тут делаем свои темные делишки ---
    5.    btc eax,ebx        
    6.    jmp @loop          
    7. @quit:
     
  5. Joes

    Joes New Member

    Публикаций:
    0
    Регистрация:
    5 янв 2008
    Сообщения:
    98
    Угу, если можно прибить исходное значение регистра.
     
  6. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    persicum
    Если оптимизация по времени, то bs, bt достаточно медленные операции, а проверить на ноль можно и test eax,eax/jz
    Код (Text):
    1.     test eax,eax
    2.     jz exit; бит равных 1 нет совсем
    3.     test eax,55555555h
    4.     jz единичные биты нечетные
    5.     и т.д.
     
  7. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Медленные то они медленные, но ведь там стоит по одной битовой команде, а это поди быстрее чем комбинации из нескольких там test или shr в цикле. Если я вставлю test,
    а в eax есть 5 бит, то пять раз этот test облажается и будет тормозить, зачем дополнительно тестить, если bsf сама ставит флаг нуля?
     
  8. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Не верю я, чтобы такой громоздкий метод дихотомии был быстрее одной команды bsf, какой бы тормозной она не была...
     
  9. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    persicum
    Было предложено несколько вариантов, с "гребенкой", номера единичных битов обнаруживаются за 5 проверок, а не за 32 как с bsf
    Если не жалко памяти - можно организовать табличный поиск вообще одной командой
    jmp Table[eax*4]
     
  10. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Мне думается, что когда говорят, что битовые команды медленней логических,
    то это только для тех случаев, когда заранее известно, какие биты нужны и можно состряпать готовую маску заблаговременно.

    А если - как в моем случае - номера нужных бит заранее не известны, то имхо битовые команды должны быть быстее ясен глаз.
    Так, btc x,y видимо должно быцтрее работать чем
    x:=x xor (1 shl y) из паскаля...

    Не понял юмора... bsf нужный бит находится за одну проверку

    16 гигов o: ?
     
  11. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    persicum
    Разбить eax на 4 последовательных байта (собственно, al, ah бесплатно получаются). Построить 1 таблицу и четыре раза к ней обратиться.
    ЗЫ
    А вообще я что-то не врубаюсь, что собственно нужно: количество единичных битов или их позиции.
     
  12. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Вот именно позиции нужны, самих ненулевых бит немного в каждом eax.
    А точнее, нужно улучшить мой код, если это возможно, поскольку свое решение я уже приводил... Ну и вообще, компетентно предложить самый быстрый вариант и с гарантией, замерить тайминги и тики, латенцию типа. Короче, самое оптимальное решение задачи последовательного скана бит, когда число ненулевых бит невелико, но в принципе нужна работоспособность и для любого их числа вплоть до 32 штук
     
  13. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    если немного, то сравнивать al с 0, а потом сдвигать eax вправо.
     
  14. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    persicum
    "внутри" bs сдвиги на 1 бит, "внутри" bt логическое умножение на маску
     
  15. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    А внутри IMULя аж 32 сдвига и 32 сложения, теперь не жить и убицца головой ап стену...

    А если в al вдруг сидит несколько бит (а вдруг?), хотя это и маловероятно, но возможно...
     
  16. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
  17. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    Похоже что IMUL как раз и оптимизируешь?
     
  18. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    persicum
    Код (Text):
    1.        test eax,eax
    2.          jz quit ;нет единичных бит совсем
    3.          mov ecx,32
    4. a1:    add eax,eax
    5.          setz bl
    6.          jnc nobit
    7. ... тут знаем, что бит, который в cl стоит
    8. nobit: test bl,1
    9.          jnz quit; кончились единичные биты
    10.          dec ecx
    11.          jnz a1
    12. quit:
     
  19. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.243
    persicum
    // оффтоп
    ну, ты самородок - редко вижу такую жуткую смесь:))
    +7
     
  20. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Очень изобретательный вариант...
    А чем не устраивает самый простой?
    И покороче будет.

    Код (Text):
    1.  xor ebx,ebx
    2. @lll:
    3.  test eax,1
    4.  jz @nobit
    5.  --- в ebx номер бита
    6. @nobit:
    7.  inc ebx
    8.  shr eax,1
    9.  jnz @lll
    Насчет shr не помню, может нужно с cl