Оптимизация проти Intel Compiller

Тема в разделе "WASM.A&O", создана пользователем emergenter, 5 окт 2004.

  1. The Svin

    The Svin New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    665
    Адрес:
    Russia
    Я пользовался старым (v 2.?) Ещё в эпоху простых пней.

    Там удобней было ляпы находить по параллелизации U/V.

    А новый как то поставил - он мне систему обрушил, такая тормозень этот новый VTUNE! Его на бейсике писали похоже причём тяп/ляп.

    Но по твоему вопросу беспокоится нечего - он идёт с тучей док включая и тюторы.

    Я кстати от него только доку и оставил - там второй том (инструкции) от Intel сделан в chm. В chm как то удобней - можно программировать поиск через API, вот единственное что полезного я там для себя нашёл.

    У Касперски (Крыса) в книжке тоже рассказы про VTUNE, он то ли некоторые главы то ли вообще здоровый кусок книжки и на русском и на английском где то выложил для публичного пользования. Спроси у него.
     
  2. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    Я против переписывания с языка высокого уровня на ассемблер только ради факта, что ассемблер теоретически быстрее.

    Но, я даже очень за оптимизацию кода, который часто вызывается.
     
  3. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    Тогда еще один аспект. Не проблема написать

    на ассемблере программы для матричной алгебры,

    проблема оттестировать их, чтобы можно дать

    рядовому юзеру. Вот поэтому и приходится

    лавировать между старыми проверенными

    фортранными текстами и коммерческими

    оптимизированными библиотеками. То же самое

    касается алгоритмов оптимизации используемых

    в компиляторе. Гений конечно придумает,

    но во сколько обойдется проверка его идеи ?!
     
  4. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    Не вижу проблемы в тестировании...



    1. Пишем библиотеку функций на ассемблере для матричных операций

    2. Пишем тестовый контейнер: програмку, которая читает из файла матрицы+результат, вызываем библиотеку и сравниваем с результатами.



    Всё автоматизировано, только надо придумать и написать входные файлы, а ещё лучше использовать ФОРТРАН для генерации такого файла.
     
  5. The Svin

    The Svin New Member

    Публикаций:
    0
    Регистрация:
    6 июл 2003
    Сообщения:
    665
    Адрес:
    Russia
    Мы движемся по одному кругу фраза

    "старыми проверенными фортранными текстами"

    говорит, что кто-то их писал, значит проблемы были уже преодолены в прошлом, и преодолены людьми.

    Мы должны либо сказать что "мы не люди такого" сорта либо, что "ничего нового написать без страшных потерь невозможно", что противоречит действительности так новые библиотеки постоянно выходят.

    Это просто проблема своего позиционирования в мире программирования, т.е. психология, никаких практических вещей связанных с математикой или прикладным кодированием в ней нет. Если главная задача кодёра - быстрые решения по документообороту в его конторе, разумеется заставлять его писать серьёзное мат обеспечение покажется ему "слишком".

    Другое дело если человек заранее готовит себя как системщик, то готовность и психологическая и проффессиональная приходят со временем.

    Дело в том, что большинство системщиков ушло и уходит в ЯВУ как основной инструмент (долгая и пережёванная неоднократно тема) поэтому любители и новички просто мало видят примеров серьёзной работы и из-за этого появляется психологический момент - иллюзия, что это как-то с ассемблером связано. На самом деле связано с людьми, так сложности языка слабосравнимы с реальными профессиональными трудностями - это правильная мат модель в сложных проектах. Это как разница между десантником (начну а там поглядим) и полководцем где метод тыка дорого стоит и нужно уметь моделировать в голове (или схемах) сложные композиции. Мой личный пример не эталон но сгодится как пример, даже в небольших проектах у меня уходит где то 95 процентов на обдумывание общей модели и лишь процентов 5 на непосредственное кодирование в редакторе. Эти 95 процентов не зависят от того на чём я буду писать - я придумываю тех. описание задачи, поиском в ней связей и подводных камней как если бы у меня был робот который мог бы закодировать за меня эту задачу, от меня в данный момент требуется лишь очень точно её смоделировать.

    А потом на 5 процентов времени я уже сам становлюсь этим "роботом" и кодирую.
     
  6. lis

    lis New Member

    Публикаций:
    0
    Регистрация:
    30 дек 2004
    Сообщения:
    23
    Адрес:
    Russia
    emergenter

    Дизассемблируй программу, собранную интеловским компилятором и использующую интеловские библиотеки и поймёшь, что она состоит из коротких многочисленных процедур, что, конечно, удобно, но если взять во внимание большие циклы, то,естественно, возникают потери.
     
  7. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    lis >




    Утверждение IMHO весьма спорное, intel C++ очень агрессивно inline'ит функции (даже те, которые не объявлены как inline ). собственно, это и есть один из способов оптимизации по скорости.



    Вообще, немного странный компилятор. Любит выравнивать функции по 4х байтной границе, что не совсем понятно.

    В случаях, когда разумно использовать word-половину регистра, зачем-то копирует посредством MOVZX в другой и потом работает уже с ним (что ведёт к увеличению кол-ва команд и размера кода). Похоже, он совсем не умеет использовать партиальные регистры, во всяком случае, мне так и не удалось заставить его это делать.

    При многократном вызове API функции не сохраняет адрес в регистре с последующим call reg32. Что-то ещё было, забыл :-(

    MSVC, например, прекрасно со всем этим справляется, и, в общем случае, лучше оптимизирует по размеру. (правда он плохо понимает inline, приходится писАть __forceinline)

    Причем он бесплатный, чего не скажешь про intel :-(
     
  8. masquer

    masquer wasm.ru

    Публикаций:
    0
    Регистрация:
    13 сен 2002
    Сообщения:
    890
    Адрес:
    Николаев








    MSVC точно так же делает...





    Размер кода к скорости никак не относится, скорее наоборот :)
     
  9. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    MSVC (по крайней мере 13.10) выравнивает точки входа в функции по границе 16 байт (если указано /Ot) Выравнивание по 4 я не видел.



    Ещё довольно часто не делает inline даже такие методы классов:
    Код (Text):
    1.  
    2. class foo {
    3. void inline method {...};
    4. };


    >




    "Скорее" - "не скорее" -- это не критерии :)

    В общем, можно принять такую теорию: более компактный код лучше для декодера и кэша.



    А в частных случаях речь идёт о количестве операций.

    Вот пример компиляции одного и того же кода:
    Код (Text):
    1.  
    2. ; MSVC
    3. 33DB          xor     ebx, ebx
    4. ...................
    5. 66:395D 10    cmp     [ebp+10], bx
    6. 75 09         jnz     004024A7
    7.  
    8. ; intel C++ compiler
    9. 0FB75424 38   movzx   edx, [word esp+38]
    10. 85D2          test    edx, edx                        
    11. 75 14         jnz     00401900


    Что будет выполняться быстрее думаю очевидно.

    Да это ещё что :) бывает и так:
    Код (Text):
    1.  
    2. 0FB7C3        movzx   eax, bx
    3. 85C0          test    eax, eax
    4. 75 10         jnz     00401958




    Вообще, я плохо понимаю смысл оптимизировать по скорости message loop :)
     
  10. leo

    leo Active Member

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

    Насчет partial registers, MOVZX и CALL reg32 (indirect calls) есть соответсвующие рулы в IA-32 Optimization и было бы странно, если бы Intel compiler их не придерживался. Предпочтительное использование test r,r вместо cmp m, i/r при сравнениях jz\jnz тоже описано (правила 50 и 51, раздел Compares).

    > "Что будет выполняться быстрее думаю очевидно" ?
     
  11. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Ok. Посмотрим, что там за правила скрываются за голыми цифрами:

    (IA-32 Intel® Architecture Optimization Reference Manual - 24896611.pdf. К слову, в книжке 248966-009 номера были другие)







    Речь идёт о сравнении посредством cmp с нулём, а не с другим регистром (если уж лезть в теорию, то сравнение регистра с самим собой может оказаться медленнее, т.к. количество портов чтения из регистра ограниченно)







    Это вообще непонятно как увязать с кодом который я привёл выше :-?



    >




    Было бы не плохо эти разделы указать, а то я на вскидку могу вспомнить только об indirect branch с вычисляемым адресом.



    Чем отличается call reg от call [mem] ?

    2й вариант это не indirect ???

    Более того, при 2м варианте вызова API есть вероятность, что адрес "уйдёт" из кэша и при повторном вызове будут задержки.

    Если же адрес в регистре, то регистр будет сохранён в стэке в прологе функции, а при выходе из неё восстановлен.

    А стэк всё всремя в кэше.

    Размер - + 2 байта на первый вызов, но каждый последующий - 4.



    Насчет partial registers, MOVZX уж не имеется ли ввиду это:







    Тогда читаем дальше:







    Или может это:







    :)



    Мои замеры показывают, что (на Athlon)



    cmp [ebp+10], bx



    выполдняется столько же, что и



    cmp [ebp+10], ebx



    Если же добавить лишнюю инструкцию, то для меня очевидно, что это будет медленнее ;)
     
  12. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    > "Если же добавить лишнюю инструкцию, то для меня очевидно, что это будет медленнее"



    Во-первых, в сравниваемых примерах число инструкций одинаково xor+cmp и movzx+test. Во-вторых, и в P6 family и в NetBurst (да наверняка и в K6,K7) бОльшую роль играет не число инструкций, а число микроопераций. В данном случае cmp m,r это 2 моп, а xor,movzx,test по 1. Поэтому в первом варианте имеем 3 моп, а во втором 2.

    Более того на P6 family одно-моповые инструкции могут декодироваться по 3 шт.за такт, а состоящие более чем из 1 мопа, декодируются только на декодере D0 в начале цикла => возможна доп.задержка на декодирование cmp m,r если она не "впишется" в последовательность 4-1-1.



    PS: Странное дело подозревать в "тупости" компилятор от производителя процессора - уж кому как не Intel лучше знать, что будет "лучше" на их камнях. Если речь об оптимизации под атлоны, то другое дело, тогда можно и посомневаться в "премудрости" Intel compiler.
     
  13. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    leo >




    Разве оно одинаково? MSVC обнуляет ebx совершенно в другом месте, и далее использует этот регистр как константу = 0 во множестве операций. (этот регистр не изменяется в stdcall, cdecl & fastcall конвенциях)



    >




    Не надо путать грешное с праведным - те одноµop'овые movzx и test имеют зависимость по данным, и не могут выполняться параллельно, так что имеем те же 2 µop при большем размере. А на PIV вообще один декодер, не стОит про это забывать!

    И, кстати, если данные signed, то используется movSx, которая не очень то и быстрая на PIV.



    >




    Я где нибудь говорил что-то подобное? Хороший компилятор, не какой-нибудь борланд, только стОит дорого.

    Для каких-то целей, возможно, и лучший, а изначально речь шла о размере кода vs MSVC.

    Хотя, AFAIK, Intel имеет к этому компилеру такое же отношение, как Microsoft к Connectix, ой тфу, Microsoft Virtual PC ;)



    А, врообще, логика конечно железная.

    Intel'у лучше знать, поэтому не верьте своим глазам =)



    movzx eax, bx

    test eax, eax



    или



    test bx, bx
     
  14. lis

    lis New Member

    Публикаций:
    0
    Регистрация:
    30 дек 2004
    Сообщения:
    23
    Адрес:
    Russia
    S_T_A_S_

    Привет! А как ты собирал программы в VC? Подключал интеловский компилятор? Если нет, то какую версию VC использовал? У меня 6-я, там посто так P4 не поддерживается.
     
  15. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    > "Intel'у лучше знать, поэтому не верьте своим глазам"



    Защищать или оправдывать Intel я не собираюсь. Может они и в самом деле тупо следуют своим правилам - не берусь судить и тем более выносить приговор.

    А вот глазам своим не всегда следует верить (особенно если глазки устали от длительного изучения архитектуры 8086 :).

    С размером кода и декодированием в примере с test bx,bx против movzx конечно все ясно. А вот по скорости выполнения на PIV эти варианты практически не различимы, хотя кому-то может и "очевидно", что "две" инструкции должны выполняться дольше чем "одна". Если бы еще точно знать, что скрывается за этой "одной" инструкцией...
     
  16. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    lis >




    Ты наверное Visual Studio (VS) имеешь ввиду? у меня нет её. В качестве IDE я использую другие проги. Компилятор от микрософта (VC 13.10) давно доступен бесплатно с их сайта, тот что в 6й студии imho уже не актуален. ICC используется так же как и VC, только меняем cl.exe на icl.exe :) Однако, если сорцы компилируются VC, не факт, что интел их переварит - он более строгий к синтаксису и отклонениям от стандарта.





    leo



    Ну опять ты абстракции какие-то говоришь, что значит
    ? Секундомером не измеришь что ли :) Если декодер один, то он сначала декодирует одну команду, а потом (!) другую.
     
  17. lis

    lis New Member

    Публикаций:
    0
    Регистрация:
    30 дек 2004
    Сообщения:
    23
    Адрес:
    Russia
    S_T_A_S_

    Я имел в виду MS VC++ 6.0
     
  18. leo

    leo Active Member

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

    Под выполнением я имел ввиду собственно execution без учета декодирования, т.е. в предположении что мопы поступают из trace-кэша (повторное исполнение тела цикла или процедуры). Wintest от Агнера-bogrus'a показывает одинаковые результаты для циклов с test bx,bx и movz+test. Это можно как-то объяснить распараллеливанием (с "соседними" инструкциями), но можно и предположить, что test r16 все таки выполняется дольше чем test r32, скажем 1 такт против 0.5+0.5=1. Должна же тут быть какая-то логика, почему Intel так упорно избегает partial registers.
     
  19. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    lis



    Ну да, я под vc понимаю компилятор, а ты - оболочку :)

    Ничего никуда не интегрировал, компилирую так: icl source.cpp





    leo



    Я всё не пойму, как научиться мерять время выполнения одной инструкции? И почему можно пренебрегать временем декодирования? А временем чтения инструкций из памяти? Может, проц сразу с винта читает в trace cache?



    >




    Да им влом лишний модуль в компилятроре писать :)