Сам себе Iczelion

Тема в разделе "WASM.BEGINNERS", создана пользователем Mikl_, 11 май 2007.

Метки:
  1. CroX

    CroX New Member

    Публикаций:
    0
    Регистрация:
    9 сен 2006
    Сообщения:
    37
    Эх, кто бы переписал уроки Iczelion'a под fasm.
     
  2. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    CroX
    Уже сделано давно.
    Mikl__
    Хорошая ветка получается, занимательная, плавно перетекла к общей оптимизации. гуд.
     
  3. Debrol

    Debrol New Member

    Публикаций:
    0
    Регистрация:
    15 май 2007
    Сообщения:
    1
    Отличная ветка, респект автору, надо тебе теперь все в кучу собрать и сделать chm свой
     
  4. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    Для чистоты эксперимента создал диалог с единственной кнопкой через редактор ресурсов (688 байт), через заполнение структур (816), программное создание кнопки в диалоге и в окне (696 и 696), создание диалога через DialogTemplate (528). О результатах судите сами...
     
  5. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    .IF это не условное ассемблирование (не путать с IF) а т.н. "высокоуровневый синтаксис" ассемблера.
    Да кстати нюанс который нигде не встречал в доках (пришлось у Hutcha выспрашивать):
    .IF eax < 5 генерирует беззнаковый код:
    cmp eax, 5
    jae ...
    Поэтому когда eax может быть как положительным так и отрицательным
    нужно писать .IF sdword ptr eax < 5 компилируемое в:
    cmp eax, 5
    jge ...

    При любом способе пробегания по списку возможных сообщений рационально сначала проверять часто посылаемые WM_TIMER, WM_MOUSEMOVE, WM_PAINT и т.п. а одноразовые WM_CREATE, WM_DESTROY выкинуть на последнее место.

    И ещё насколько я понимаю (если что Leo поправит) механизм предсказания переходов один на все задачи, поэтому к приходу очередного сообщения (достаточно редкое событие) другие задачи повытесняют из ВТВ все "предидущие наработки" и оптимизированный вариант типа "дерево" может проигрывать варианту типа "поиск в таблице" за счёт большего количества неверно предсказанных переходов.
     
  6. W4FhLF

    W4FhLF New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2006
    Сообщения:
    1.050
    Это ты имел ввиду стандартный ImageBase=400000h?
     
  7. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Да, SBYTE, SWORD, SDWORD - это старые грабли.
     
  8. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    asmfan
    Сижу, пересматриваю Кип Р.Ирвинг "Язык ассемблера для процессоров Intel" стр 295-296
    Код (Text):
    1. .data
    2. val2 SDWORD -1
    3. result SDWORD ?
    4. .code
    5. mov eax,6
    6. .IF eax>val2
    7. mov result,1
    8. .ENDIF
    9. будет сгенерировано
    10. mov eax,6
    11. cmp eax,val2
    12. jle @A
    13. mov result,1
    14. @A
    запустил, сгенерировал, действительно так, но если "val2 dd 1" будет jbe
     
  9. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    Y_Mur
    Все что связано с WM_CREATE можно расположить сразу после CreateWindow до цикла обработки сообщений, а вот насчет дерева я не понял :dntknw:
     
  10. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Я вообще-то про то, что ты пишешь про оптимизацию обработчика сообщений, но везде рассматриваешь их в последовательности: WM_DESTROY,WM_CREATE,WM_PAINT,WM_TIMER, т.е. сначала делаешь сравнение с одноразовыми (WM_DESTROY,WM_CREATE), а затем с теми что идут сплошным потоком (WM_PAINT,WM_TIMER), соответственно если сделать наоборот, то количество лишних проверок существенно сократится (конечно визуально по скорости работы программы ты этого не заметишь, но раз уж оптимизировать, то оптимизировать :)

    Очень хорошо, что ты приводишь пример организации бинарного дерева:
    Но в обработчике оконных сообщений имхо этот метод будет постоянно спотыкаться об неверно предсказанные переходы и из-за этого может оказаться менее эффективным чем поиск в таблице сообщений отсортированной по частоте прихода сообщений см. выше
     
  11. kero

    kero Модератор SOURCES & 2LZ Команда форума

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    Mikl__

    1)
    Мелочное замечание об имени класса главного окна:
    на самом деле можно и Edit-ом обозвать, если приложение не использует настоящие Edit-ы.

    2)
    Наверное, следовало бы порадовать начинающих оптимизаторов благой вестью о L2EXTIA,
    перегоняющей masm-овские либы в inc-файлы с _imp__.

    А в аттаче - утилитка by Vortex (http://www.masm32.com/board/index.php?topic=416.0),
    которая конвертирует не либы, а исходники, причем не только для masm, но и для fasm и др.

    (Кстати, как насчет конвертера исходников Iszelion-а в исходники Mikl__-а ? :) )
     
  12. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    kero
    Спасибо огромное.
    Я примерно это и хотел сказать, но... обзываю AppClass и AppName "BUTTON", случайно "забываю" вызвать RegisterClass и получаю окно в виде одной большой кнопки:)
    Я за:)), что для этого нужно? А давайте сделаем Вижуал Асм :lol:
     
  13. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    Y_Mur
    Можно построить обработку сообщений на основе деревьев с использованием CMOV и CMPXCHG
     
  14. AndreyATC

    AndreyATC New Member

    Публикаций:
    0
    Регистрация:
    16 май 2007
    Сообщения:
    60
    Mikl__
    у мну рационализаторское предложение!
    напиши ка тотуриал по x86-64 процам)
     
  15. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    AndreyATC
    Всему, свое время ;)
     
  16. AndreyATC

    AndreyATC New Member

    Публикаций:
    0
    Регистрация:
    16 май 2007
    Сообщения:
    60
    Будем ждать=)
     
  17. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    Пусть наше приложение завершается invoke ExitProcess,0. Тогда можно упростить цикл обработки сообщений, без проверки возвращает ли GetMessageA в eax 0
    Код (Text):
    1. message_loop: push ebx  ;цикл обработки сообщений
    2.     push ebx
    3.     push ebx
    4.     push edi
    5.     call _imp__GetMessageA@16  
    6.     push edi
    7.     call _imp__DispatchMessageA@4     ;вернуть управление Windows        
    8.     jmp short message_loop
    А в обработчик WM_DESTROY вместо PostQuitMessage ставится ExitProcess
    Код (Text):
    1. @@WM_DESTROY: push 0    ;завершение программы
    2.         call _imp__ExitProcess@4
     
  18. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Оптимизация в ущерб надёжности.
    Советую всегда проверять возвращаемые значения, а для ф-ии GetMessage проверять не только на ноль, а на -1, т.е.
    Код (Text):
    1.     call    _imp__GetMessageA@16
    2.     test    eax,eax
    3.     jle .fail
     
  19. Mikl_

    Mikl_ New Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2006
    Сообщения:
    907
    Реализуем мультиветвление при помощи косвенного перехода по таблице. Для увеличения скорости просмотра очереди сообщений строим таблицу MsgTable, где номер элемента таблицы соответствует номеру сообщения. Сами табличные элементы представляют собой адреса (процедур), где эти сообщения обрабатываются. Чтобы не перечислять все 400h (1024) сообщений, можно определить номер максимального сообщения Max_Msg и если номер сообщения больше максимального, сразу отправлять на обработку сообщения по умолчанию (метка @@default). Сообщения, не обрабатываемые в процедуре WinProc, также имеют адрес обработки соответствующий адресу метки @@default. При этом время выполнения перехода всегда одинаково для всех вариантов мультиветвления.
    Код (Text):
    1. mov eax,Msg
    2. cmp eax,Max_Msg
    3. ja @@default;MsgTable - таблица с адресами обработки
    4. jmp MsgTable[eax*4];каждый адрес обработки расположен через 4 байта
    Но у этого способа есть и оборотная сторона. К сожалению, большая скорость обработки сообщений будет компенсирована раздувшейся таблицей MsgTable. Программы с обработкой сообщения WM_NULL =0h мне пока еще не попадались. Обработку сообщения WM_CREATE=1h можно расположить сразу после вызова функции CreateWindow до цикла обработки сообщений. Сообщение WM_DESTROY=2 должно обрабатываться в любой программе. То есть можно сократить нашу таблицу еще на 2 элемента (WM_NULL, WM_CREATE)
    Код (Text):
    1. mov eax,Msg
    2. sub eax,Min_Msg
    3. cmp eax,Max_Msg-Min_Msg
    4. ja @@default
    5. jmp MsgTable[eax*4]
    Наиболее часто используемые сообщения: WM_PAINT=0Fh, WM_CHAR=102h, WM_COMMAND=111h, WM_TIMER=113h, WM_LBUTTONDOWN=201h, WM_RBUTTONDOWN=204h и т.д. Пусть адреса необрабатываемых сообщений в нашей таблице (матрице) равны 0. Мы получили разреженную матрицу, у которой лишь незначительная часть элементов отличны от нуля, причем все ненулевые элементы распределены внутри таблицы произвольным образом. Для того чтобы не расходовать лишнюю память на запись нулей, ненулевые элементы можно занести в хэш-таблицу, причем в этом случае номер сообщения WM_XX, указывающая позицию элемента в матрице, выступает в качестве его «ключевого слова». Хэш-функция F должна возвращать адрес элемента в хэш-таблице т.е.
    F(WM_COMMAND)=адрес(@@WM_COMMAND)
    Но это теория, а вот как должна выглядеть эта самая хэш-функция на практике?
     
  20. maxdiver

    maxdiver Max

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    308
    Адрес:
    Саратов
    Mikl__
    Раз таблица разреженная, то зачем её хранить в виде матрицы? Сделать список (массив) из отсортированных элементов (которые ненулевые, естественно), и каждый раз в нём находить нужный элемент бинарным поиском. При данных ограничениях затраты на бин. поиск будут сравнимы с затратами на вычисление хэш-функции.