Главная | Комментарии | О проекте
Чтение RSS
Суперсайт
Главная Контакты Карта сайта Добавить в избранное
  • Кто OnLine

    Всего на сайте: 8
    Гостей: 1
    Пользователи: SKAJIbnEJIb
    Роботы: Yandex Bot, crawl Bot, Yandex Bot, Yandex Bot, robot Bot, Google Bot

    Опрос пользователей

    Для какого мода Вы пишите плагины?

    • Популярное

    Рекомендуем

    • AMX Mod X
    • up.org.ua

    Наши друзья


  • Автор: HoLLyWooD Дата: 10-01-2012, 23:27 Просмотров: 3765

    Урок 10. Применение битовых операций

    Мы можем использовать битсуммы вместо булевых массивов.

    Примечание: Важно отметить, что если, к примеру, у нас есть 1 = 0000 0000 0000 0000 0000 0000 0000 0001 и выполняя 1 << 32 мы получаем: 1 0000 0000 0000 0000 0000 0000 0000 0000, как видно 1 выходит за пределы. Поэтому при 32 игроках на сервере, мы не получим верную работоспособность. Для этого надо отнять 1. Вместо 1-32 у нас будет 0-31.

    К примеру, вместо:

    new bool: is_alive[33]


    Запишем:
    new bitsum_is_alive 


    Вместо:
    if (is_alive[id]) 
    {
    }


    Запишем:
    if (bistum_is_alive & (1<<(id-1))) 
    {
    }


    Вместо:

    is_alive[id] = true

    is_alive[id] = false


    Запишем:

    bitsum_is_alive |= (1<<(id-1))

    bitsum_is_alive &=  ~(1<<(id-1)) 


    Если рассматривать, к примеру, присвоение:
    is_alive[id] = true


    или как мы заменили:
    bitsum_is_alive |= (1<<(id-1))


    где id = 1 при bitsum_is_alive = 0000 0000 0000 0000 0000 0000 0000 0000, то есть игрок id = 1, первый на сервере.
    Вычисления:

    1. id-1 = 1-1 = 0
    2. 1<<(id-1) = 1 << 0 =
    0000 0000 0000 0000 0000 0000 0000 0001 << 0 = 0000 0000 0000 0000 0000 0000 0000 0001
    3. bitsum_is_alive | (1<<(id-1)) =
    0000 0000 0000 0000 0000 0000 0000 0000
    |
    0000 0000 0000 0000 0000 0000 0000 0001
    =
    0000 0000 0000 0000 0000 0000 0000 0001
    4. bitsum_is_alive = bitsum_is_alive | (1<<(id-1)) = 0000 0000 0000 0000 0000 0000 0000 0001


    А если допустить, к примеру, что bitsum_is_alive = 0000 0000 0000 0010 0100 0000 0100 0001, что говорит нам о том, что игроки у которых id равно 1, 7, 15, 18 - живы, так как у них бит равен 1, отсчет битов ведется с конца. То присвоение игроку id = 7 (выделенный красный бит) статуса мертвый (бит в 0), будет происходить след. образом (как мы заменяли код выше):

    bitsum_is_alive &=  ~(1<<(id-1)) 


    Вычисления:
    1. id-1 = 7-1 = 6
    2. 1<<(id-1) = 1<<6 =
    0000 0000 0000 0000 0000 0000 0000 0001 << 6 = 0000 0000 0000 0000 0000 0000 0100 0000
    3. ~(1<<(id-1)) = 1111 1111 1111 1111 1111 1111 1011 1111
    4. bitsum_is_alive & ~(1<<(id-1)) =
    0000 0000 0000 0010 0100 0000 0100 0001
    &
    1111 1111 1111 1111 1111 1111 1011 1111
    =
    0000 0000 0000 0010 0100 0000 0000 0001
    5. bitsum_is_alive = bitsum_is_alive & ~(1<<(id-1)) = 0000 0000 0000 0010 0100 0000 0000 0001.


    Мы получили bitsum_is_alive = 0000 0000 0000 0010 0100 0000 0000 0001

    Можно ли как-то оптимизировать работу?
    Можно сделать stock функцию:

    stock is_user_alive(id) 
    {
          return (bistum_is_alive & (1<<(id-1))) ? 1 : 0
    }


    Или макрос:
    #define is_user_alive(%1) (bistum_is_alive & (1 << (%1-1))) ? 1 : 0 




    Автор статьи: DJ_WEST
    Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
    Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.
    Урок 10. Применение битовых операций
    arwel

    --
    ICQ: --
    Публикаций: 0
    Комментариев: 0
    Репутация: -  0  +

    Спасибо. У меня вопрос, как сильно использование этих битов оптимимзирует плагин?
    Monstr™

    29.09.2011
    ICQ: 631967458
    Публикаций: 12
    Комментариев: 22
    Репутация: -  0  +

    arwel биты очень хорошо оптимизируют работу так как компьютору работать с битами на много удобней чем с булевыми массивами, следовательно это увеличивает скорость обработки кода и его еффективность. С битами можно делать не только булевые маcсивы.
    HoLLyWooD

    26.09.2011
    ICQ: 8272341
    Публикаций: 3
    Комментариев: 10
    Репутация: -  0  +

    arwel,
    Плагину не нужно будет преобразовывать данные в биты для передачи процессору. Я считаю что конкретно в АМХХ биты не несут БОЛЬШОЙ роли в оптимизации.
    arwel

    --
    ICQ: --
    Публикаций: 0
    Комментариев: 0
    Репутация: -  0  +

    Это очень полезно когда работаешь с энтити. В многих плагинах видел как создают масив[512]. Думаю, в этом случае использование битов хорошенько оптимизирует плагин.
    droper

    --
    ICQ: --
    Публикаций: 0
    Комментариев: 0
    Репутация: -  0  +

    Сомневаюсь, что использование всех этих операций как-то ускоряет или оптимизирует работу плагина. Вот небольшой кусок тестового плагина
    new alive[ 33 ];
    new bits_alive;
    public alive ( id )
    {
        alive[ id ] = true;    
        #emit break;    
        bits_alive |= 1 << ( id - 1 );
        #emit break
    }
    а вот его дизассемблированный код
    PROC  alive
        zero.alt        

     ; 2
        load.s.pri   0xC ; 3
        bounds       0x20; 4
        idxaddr        &
    amp;
    nbsp; ; 2
        move.alt        

     ; 2
        const.pri   0x1  ; 2
        stor.i        &a
    mp;n
    bsp;  ; 10
                 &n
    bsp;       ; 25

        load.pri   0x84  ; 3
        push.pri        

     ; 3
        load.s.pri  0xC  ; 3
        add.c      -0x1  
    ;
    ;; 3
        const.alt   0x1  ; 2
        xchg        &
    ;nbs
    p;    ; 3
        shl         
    ;     ; 6
        pop.alt        &
    amp;
    nbsp; ; 4
        or         
          ; 3
        stor.pri    0x84 ; 3
                 &n
    bsp;       ; 33
    ENDP
    как видно строка alive[ id ] = true выполняется в семь операций, а bits_alive |= 1 << ( id - 1 ) в 10 операций.
    Цифры после ; это кол-во операций ассемблера (можно посмотреть в исходниках amxx файл amxexecn.asm), даже тут булевая операция выигрывает (25 против 33 комманд).
    Valer4

    --
    ICQ: --
    Публикаций: 0
    Комментариев: 0
    Репутация: -  0  +

    Тестировал, с битами быстрее, точно не помню, то ли в 2 то ли в 1,5 раза.
    В С++ наоборот пишут медленнее, т.к. процессор оптимизирован для работы с байтами, но в АМХ почему то быстрее.
    И минус 1 не обязательно, 32 будет в нуле, а не пропадёт.
    Можно хоть диапозон от 32 до 63 использовать.
    63 будет в 63 - 32 = 31 ячейке.

    Информация

    Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.
Наверх

Реклама