Как оптимизирует MSVC 7.1 ?

Тема в разделе "WASM.WIN32", создана пользователем _DEN_, 18 апр 2005.

  1. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    > И что самое интересное - в начале и в конце push / pop ecx, но ecx нигде не юзается?..



    Это так память в стеке выделяется для переменной размера DWORD
     
  2. semen

    semen New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2004
    Сообщения:
    334
    Адрес:
    Russia
    Asterix

    Точняк, какой же я невнимательный... еще одно доказательство того что торопиться не стоит..

    Но еще остался ebx, который можно портить не сохраняя если он не нужен далее, но без вложенности в main и без WPO такая неосторожность не показатель...

    А еще можно в стеке затирать аргументя main`а - ониж не юзаются и обойдемся вообще без пушей, но как говорится селяви.
     
  3. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Asterix



    Какой хитрый компиллер :) Если переменных больше одной, то все "по-человечески", sub-ом. А тут вон что творит :)



    Кстати, еще вот что интересно. Как-то видел что esp откатывался не через sub esp,xxx, а через add esp,0ffffffxxh. С чем это может быть связано?
     
  4. semen

    semen New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2004
    Сообщения:
    334
    Адрес:
    Russia
    _DEN_





    Похоже на фрагмент выравнивания стека на 8\16 (обычно, для даблов и __m128), тока не add а and.
     
  5. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    semen



    Не, именно add. Обычный откат для временных переменных. Вот только через add. Вот это и непонятно...
     
  6. semen

    semen New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2004
    Сообщения:
    334
    Адрес:
    Russia
    _DEN_

    Скорее всего ошибаешься - поискал в куче листингов - add к esp на отрицательные числа нету, а вот and - дофига.
     
  7. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Хмм... Ладно, поищу...
     
  8. captain cobalt

    captain cobalt New Member

    Публикаций:
    0
    Регистрация:
    21 дек 2003
    Сообщения:
    222
    Адрес:
    /ru/perm
    По поводу add esp, вместо sub.

    У этих команд есть опкоды со знаковым расширением непосредственного байтового операнда. Диапазон значений для знакового байта [-128..+127] Поэтому команда add esp,-128 может быть закодирована более коротким опкодом, чем sub esp,128.
     
  9. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    captain cobalt

    Свежая мысль. Надо посмотреть.
     
  10. semen

    semen New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2004
    Сообщения:
    334
    Адрес:
    Russia
    Да - я ведь смотрел сишные листинги, а не дизассемблер, там как будет закодирована инструкция можно не увидеть, так-же как с npad 3 будет не 3 нопа...

    Кстати все-таки врядли, потому что запомнилось add esp,0ffffffxxh - а это явно не короткий вариант, хотя может ида так показывает...
     
  11. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    возможно (хотя маловероятно в Си) что sub устанавливает carry flag
     
  12. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Еще вопросих всплыл. Зачем компилер часто между cmp / test / or и jxx ставит mov ?
     
  13. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    jxx всеравно нужно ждать пока выполнится команда устанавливающая флаги и отреагирует предсказание, а в это время можно выполнить и mov (если остальные порты исполнения простаивают, и даже не один), возможно так он помогает перегруппировать мопы, или он вообще левый mov вставляет?
     
  14. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    bogrus



    Не, не левый, осмысленный :) Значит тут тоже какой-то выигрыш идет?
     
  15. alpet

    alpet Александр

    Публикаций:
    0
    Регистрация:
    21 сен 2004
    Сообщения:
    1.221
    Адрес:
    Russia
    от вставки mov между операциями сравнения, выiгрыш если и будет, то только для mov (ну скажем операнды подоспеют). Как я заметил операции cmp/test/or и jxx/setxx в большинстве случаев выполняются одновременно (по крайней мере на AthlonXP), и даже если не одновременно (cmp al, bl\jmp eax)- для такой близкой перестановки и существует диспетчеризация комманд.
     
  16. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Я тоже вставляю mov перед jcc. Чтобы jcc не бежал впереди паровоза, провоцируя пенальти. Если это например jcc в конце цикла, то mov или другая инструкция, которая будет выполнена на следующей итерации, главное, чтобы она не требовала результатов предыдущего cmp/test и не изменяла флаги. И от пенальти избавляемся, и полезное действие делаем.

    Если такой полезной инструкции нет, то иногда просто mov ebp,ebp делаю.
     
  17. alpet

    alpet Александр

    Публикаций:
    0
    Регистрация:
    21 сен 2004
    Сообщения:
    1.221
    Адрес:
    Russia
    Декодеры современных процессоров заглатывают и исполняют порой по 3 инструкции за такт, так-что для реальной-гарантированной задержки надо вставлять либо инструкцию которая параллельно с jxx не выполняется, либо две инструкции. На пайп тестах это бывает хорошо видно - добавил ты одну комманду mov, она как раз вместе cmp & jxx вместе оказывается в группе выполнения.
     
  18. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Чего то вы странные вещи говорите о jcc.



    На суперскалярных процессорах, jcc ничего не ждет и ничего не делает, кроме как засылает себя в branch предиктор и со спокойной совестью идет в отставку. Поэтому ее латентность = 0 или 1 такт. А установка флагов и работа бранч-предиктора идут на следующей стадии конвейера параллельно с обработкой последующих и возможно предыдущих инструкций. А длина конвейера как известно не менее 10 стадий, а в гипер-пайпланах и за тридцатник зашкаливает. Что это означает ? Это означает, что когда jcc только добралась до исполнительного блока, и уж тем более когда начинается проверка условия jcc - процессор уже не менее как 10 тактов занят подготовкой спекулятивного исполнения следующего за jcc кода (на основании предыдущего решения бранч-предиктора). И если предсказание оказалось не верным, то - труба - сбрасывай неверно загруженный конвейер и начинай грузить с другого адреса. И никакой mov тут не спасет (разве ж только div ;)) И дело тут не в тактах, а в количестве микроопераций, которые уже были спекулятивно загружены в конвейер после jcc и которые придется выбросить в случае ошибки предсказания.
     
  19. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    leo



    Хорошо, мудрый дяденька, скажи тогда зачем компиллеры mov пихают?
     
  20. alpet

    alpet Александр

    Публикаций:
    0
    Регистрация:
    21 сен 2004
    Сообщения:
    1.221
    Адрес:
    Russia
    Дык наверное потому и пихают, что операнды не готовы. Хотя судить надо по коду, а не наобум.