Flood-it!

Entertainment for 5 minutes, hours, days
  • Leency wrote: а) как узнать размер стека я не знаю, но он ведь всегда равен 100, или нет? Заменил CreateThread(#help,#stak); на CreateThread(#help,#stak+100); ничего не изменилось. Всё работает и я решил оставить как было раньше. Тут пусть lev разбирается, он круче))
    Ну размера стека будет таким, какой тебе нужен :) А то, что ничего не изменилось, это только на первый взгляд. Ведь по идее в случае CreateThread(#help,#stak) обращение к стеку будет портить данные, которые находятся перед stak, а сам stak вообще никак не будет использоваться. В данном случае перед stak расположен буфер proc_info Form, старшие (1024-72) байт которого никак не используются, поэтому никаких ошибок не возникает. Но ничто не мешает компилятору расместить неиницализированный stak в каком-нибудь другом месте (например, в конце исполнимого кода программы), тогда оба потока могут дать дуба.
  • Про то что указатель надо ставить в конец области, а не в начало, я уже в чате писал - но зачем обращать внимание на комментарии какого-то хуя с горы. "Нам" ЯВУшникам море по колено.
  • IgorA wrote:

    Code: Select all

    rand_x dd 0
    
    align 4
    rand_next:
    ;x(k+1) = (a*x(k)+c) mod m
    ; a=22695477, c=1, m=2^32
    push eax
            mov eax,dword[rand_x]
            imul eax,22695477
            inc eax
            mov dword[rand_x],eax
    pop eax
            ret
    Это есть плохо. Код

    Code: Select all

            push eax
            mov eax,dword[rand_x]
            imul eax,22695477
            add eax,1 
            mov dword[rand_x],eax
            pop eax
    
    Работает (по крайней мере в linux) на 50% быстрее. Если всё это загнать в цикл, то код с inc/dec проиграет сишному коду (с -O3) в скорости в четыре раза. Не знаю как для других, а мне очень интересно писать код на ассемблере и Си, компилировать, и затем сравнивать, что быстрее работает, и изучать, почему.
  • В смысле, проинлайнить вызов крохотной функции? Естественно, это ускорит жизнь, но раздует код. Или заменить inc на add? На фоне imul это не может дать 50% выигрыша. Если последнее, то наверняка дело в том, что из-за изменения размера плывут все дальнейшие адреса, и какие-то переменные или функции - align 4 для функции недостаточно - становятся выровненными.
    Сделаем мир лучше!
  • inc и dec модифицируют только часть флагов, что создаёт зависимость от всех предыдущих записей в регистр флагов. Поэтому Интел рекомендовала заменять их add и sub.
    The INC and DEC instructions modify only a subset of the bits in the flag register. This creates a dependence on all previous writes of the flag register. This is especially problematic when these instructions are on the critical path because they are used to change an address for a load on which many other instructions depend.
  • Serge wrote:inc и dec модифицируют только часть флагов, что создаёт зависимость от всех предыдущих записей в регистр флагов. Поэтому Интел рекомендовала заменять их add и sub.
    The INC and DEC instructions modify only a subset of the bits in the flag register. This creates a dependence on all previous writes of the flag register. This is especially problematic when these instructions are on the critical path because they are used to change an address for a load on which many other instructions depend.
    Только совсем гремучие чайники могут путаться с флагами inc/dec
    Ну еще наверное разработчики х86 из Интела :lol:
    А вообще (с железячной точки зрения) inc/dec не только короче, но еще и экологичнее чем add/sub. Потому что при прочих равных условиях меньше вентилей требуется переключать в ALU и в конвейере -- экономьте электроэнергию!
    Евангелие от Иоанна: стих 1

    Code: Select all

    ; В начале было Слово:
    B32:        mov     ax, os_stack       ; Selector for os
    [/size]
  • CleverMouse wrote:В смысле, проинлайнить вызов крохотной функции? Естественно, это ускорит жизнь, но раздует код. Или заменить inc на add? На фоне imul это не может дать 50% выигрыша. Если последнее, то наверняка дело в том, что из-за изменения размера плывут все дальнейшие адреса, и какие-то переменные или функции - align 4 для функции недостаточно - становятся выровненными.
    Ох, ты права. Дело в выравнивании. Поправил align, скорость из-за этого падала.
  • Вообще-то я встречал упоминание, что на части процессоров add быстрее чем inc. В компиляторах также почему-то часто встречается замена sub на add, если работа идет с одним из постоянных значений. Например, когда в стеке под хранение локальных переменных место выделяется.
  • на суперскалярных процах add может распараллеливаться с некоторыми другими командами, но не со всеми. И в любом случае инкремент счетчика цикла требует ровно 1 такт, что с inc, что с add.

    Но все это распараллеливание загибается раком, если ломается кэш. А кэш имеет обыкновение ломаться даже в Колибри. Потому что WinMap сильно раздутый.

    Когда весь цикл умещается на одну кэш-страницу - тогда он будет крутиться с максимально возможной скоростью, причем вероятность этого при inc/dec существенно выше, чем с add/sub.
    diamond wrote:Колибри - не только очень быстрая, но еще и очень маленькая ОС
    Потому и очень быстрая, что очень маленькая.
  • Оптимизация по размеру не всегда даёт выигрыш в скорости. Для P4 с его мизерным кешем это может быть критично, а декодер Атлонов например очень любит выравнивание кода на 4 байта в циклах и ветвлениях. Ещё AMD до вторых Феномов не умела рассчитывать esp в цепочках push/pop и
    sub esp, ...
    mov [esp],
    mov [esp+4]
    mov [esp+8] работало быстрее нескольких push.
    А Интел не любили команду loop. У каждой микроархитектуры свои заморочки.
    art_zh
    Чайники или нет, но ложные взаимозависимости создают серьёзные проблемы для суперскалярных архитектур. Не случайно Интел и АМД рекомендуют использовать обнуляющие xor reg, reg или sub reg, reg для сброса ложных зависимостей между отдельными частями кода.
  • Serge wrote:У каждой микроархитектуры свои заморочки.
    И я про то же. Как можно вручную оптимизировать код и сравнивать время выполнения команд, если их суперскалярный микрокод на каждой кривой козе реализован по-своему?

    Зато я точно знаю, что dec eax всегда в 5 раз короче, чем sub eax, 1 (про энергопотребление пока замнем для ясности). Поэтому даже если я поставлю выравнивание кода на 4 байта - то всегда выиграю и в размере, и в эффективности кэширования.

    Правда, в некоторых (редких!) случаях возможен проигрыш в скорости - не более чем на 1 такт и то при очень удачном распараллеливании регистровых команд. Но что такое 1 такт по сравнению с десятками холостых тактов при промахе кэша?

    Выравнивание адресов - да, нужно. Невыравненный адрес - это 1-2 лишних процессорных тактов в кэше, или несколько "длинных" шинных тактов при промахе.
  • в 5? Иногда в 3, емнип.

    Code: Select all

    83 c0 01                add    $0x1,%eax
    83 c3 01                add    $0x1,%ebx
  • Да, твоя правда -

    Code: Select all

    add eax, byte 1

    весит только 3 байта.
    Так что поправлюсь: inc дает выигрыш при 4-байтовом выравнивании не каждый раз, а только в 50% случаев.
    А вероятность вылета с отдельной кэшируемой страницы при этом уменьшается не на 6%, а только на 3%
  • Небольшой недочёт. Для начала новой игры нужно жать кнопку, вопрос - зачем? Отрисовали win, подождали 2 сек и вывели новое поле.
  • Who is online

    Users browsing this forum: No registered users and 5 guests