1. Assembler / Говнокод #3500

    +229

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    ;uint64_t foo(uint32_t x, uint64_t y) { return x*y; }
    
    sub esp, 0×8
    mov edx, [esp+0x14]
    mov ecx, [esp+0xc]
    mov eax, [esp+0x10]
    mov [esp+0x4], esi
    mov esi, edx
    imul esi, ecx
    mul ecx
    mov [esp], ebx
    mov ebx, [esp]
    add esi, edx
    mov edx, esi
    mov esi, [esp+0x4]
    add esp, 0×8
    ret

    оптимизированое умножение - gcc 4.2.4

    Запостил: 3.14159265, 17 Июня 2010

    Комментарии (44) RSS

    • кстати gcc-4.3.2 гораздо умнее
      mov eax, [esp+0x4]
      mov ecx, [esp+0xc]
      imul ecx, eax
      mul dword[esp+0x8]
      lea edx, [ecx+edx]
      ret

      //и все-равно lea edx, [ecx+edx] - тупо
      блин , токо заметил сгетил 3500 пост 8-))
      Ответить
      • Нужно постить пони!
        Ответить
        • понЕ нужно постить на 1000,2000,1111 итд
          3500 - это не ТРУъ гет
          Ответить
          • у меня есть отличный поне, но он для 4000 или даже лучше для 4444 гета
            Ответить
            • показать все, что скрытоK8owen(*kqwbn)OLNw-(LKJNASJLKNFDOIn<nDSAI98AS
              ljioDSAFNJK(olNWQ,Ns)pjMKWKNbosp02Nd*)(i q#@wNLKn)((j@wjkendklndlkj()@lknKIJ09EWD KLN(JIEKNLKENAD9PLJFD9ESDOIJ09PDJEIJ9Emj )o(9N09IENJF090ijekuebj,IлгТЛТВДБТуцдшОЩ ЗОЦЫВтбюwjlon)LknewsklneШ*луХУЙfw909JLKn efs980jnwelkjnf9sd0jhgfKBasp0abn)NKbsA,K BpolNWKJBAPJSKJNloPJASKJNp:WJMADL*inkljN ASOI,noWQELIN98Oln,asmBNZon,lmnbawsol<LN sallo9ijndsa,jnOLwslkjnalpo9LJ>,nedloihs poKLJLnadsliqw,.
              Ответить
              • я это расшифровал!
                Ответить
                • У вас IQ +200? Инфа 100%? Поделитесь инфой. :)
                  Ответить
                • А вот мне мешают расшифровать вот эти знаки-вопросики:
                  � �
                  Ответить
    • показать все, что скрытону тупой...
      Ответить
    • показать все, что скрытоОпять говно эти асемблеры мудаебы
      Ответить
    • Дятел, ты хоть сотую часть GCC оптимизатора осиль понять, а потом будешь тут свои "находки из трюма" выкладывать.
      Гений, робана ёт, оптимизаций.
      Ответить
    • > оптимизированое умножение - gcc 4.2.4

      какие флаги использовал?

      по отсутствию всяких разных извращенных инструкций - и 64-бит инструкций - можно предположить что данный код преднамерено совместим с i586. что может и быть объяснением.

      gcc-4.4 -O3 -march=k8 :

      00000000 <foo_u64>:
         0:   55                      push   %ebp
         1:   89 e5                   mov    %esp,%ebp
         3:   53                      push   %ebx
         4:   8b 45 08                mov    0x8(%ebp),%eax
         7:   8b 55 10                mov    0x10(%ebp),%edx
         a:   8b 4d 14                mov    0x14(%ebp),%ecx
         d:   8b 5d 0c                mov    0xc(%ebp),%ebx
        10:   0f af c8                imul   %eax,%ecx
        13:   0f af da                imul   %edx,%ebx
        16:   f7 e2                   mul    %edx
        18:   01 d9                   add    %ebx,%ecx
        1a:   5b                      pop    %ebx
        1b:   c9                      leave  
        1c:   8d 14 11                lea    (%ecx,%edx,1),%edx
        1f:   c3                      ret


      и к слову "lea" как я слышал это по рекомендации самого Intel вместо add. причины точно уже не помню.
      Ответить
      • x32, потому нет 64 битных инструкций
        да и версия древняя

        кстати 4.32 в моем первом посте пооптимальней делает

        >>"lea" по рекомендации самого Intel вместо add
        если не затруднит линк какой-нибудь запостите - просто интересно
        Ответить
        • > если не затруднит линк какой-нибудь запостите

          линка у меня нету. я просто в старые времена gcc мейл листы почитывал. можешь попробовать там сам поискать.

          там много всего бегает, включаю вот такие чудеса.
          Ответить
          • я тоже их иногда почитываю ))
            спс, буду искать
            Ответить
            • к слову меня посетила идея почему lea может помогать производительности: комманда скорее всего будет выполнятся на MMU а не на ALU. если ALUs все еще чем то заняты, lea все равно сможет уже выполнится.
              Ответить
              • думаю причина не в этом, здается мне ALU и MMU используют одни и те же блоки для экономии места на кристале, как MMX,и FPU одни и те же регистры и одни и те же блоки для вычислений
                а вот то что проц знает что делать после сложения/умножения дает ему бонус.
                Это примерно как ускорение conditional jumpoв после cmp в Core2.

                то есть получается gcc-4.3.2 and later генят в данном случае практически оптимальный код
                Ответить
                • кстати нашел и пруф о lea
                  http://www.arl.wustl.edu/~lockwood/class/cs306/books/artofasm/Chapter_6/CH06-1.html
                  The final two instructions above, lea bx,4[bp+si] and lea ax,-123[di] provide additional examples of lea instructions that are more efficient than their mov/add counterparts.

                  On the 80386 and later processors, you can use the scaled indexed addressing modes to multiply by two, four, or eight as well as add registers and displacements together. Intel strongly suggests the use of the lea instruction since it is much faster than a sequence of instructions computing the same result.
                  Ответить
                  • В случае индексного доступа это логично.
                    Думаю что между

                    LEA мойрегистр, мояпеременная
                    и
                    MOV  мойрегистр, OFFSET мояпеременная


                    разницы нет.

                    А вот между
                    LEA мойрегистр, мояпеременная[42]
                    и
                    MOV  мойрегистр, OFFSET мояпеременная
                    ADD мойрегистр,42


                    есть. Особенно если выполнить ее 100500 раз.
                    Ответить
                    • собственно да, но только все-таки mov чутка быстрее
                      думаю add edx,ecx по скорости не уступает lea edx, [ecx+edx], иначе все бы использовали lea где только можно
                      но вот для случаев lea bx,4[bp+si] - тут она действительно полезна

                      так на асме и пишутся места которые 100500 раз выполняются ))
                      Ответить
                      • по моему lea не дает производительности со времен PPro... но при помощи lea можно сделать быстрое умножение на 3,5 и 9
                        Ответить
                        • .
                          Ответить
                        • Да, именно так.

                          Initially LEA был эффективнее чем вручную делать ADD потому что выполнялся на специально заточенном адресном блоке (На AGU а не на MMU кстати, потому что MMU занимался только преобразованием линейного адреса в страницы).

                          Но уже примерно с P6, с превращения x86 в risc с микрокодом это уже не так. Теперь LEA удобен разве что "быстрым умножением" и более чистым (если писать вручную) кодом
                          Ответить
                          • Т.е. теперь они его транслируют в сдвиг и джва сложения?
                            Ответить
                            • Зависит от того, какие есть блоки в конкретной микроархитектуре)

                              Я всего-лишь хотел сказать что наивно считать что в современных cpu реально вот есть выделенный AGU на котором считаются адреса и что дескать это реально быстрее потому что AGU заточен под это, а "ручное" ADD будет на ALU и будет хуже.

                              Мне кажется что это такое представление о CPU времен 8088.


                              ЗЫ: Вот тут в комментах целая гопа так же считает
                              https://stackoverflow.com/questions/1658294/whats-the-purpose-of-the-lea-instruction

                              миллионы не могут ошибаться
                              Ответить
    • >;uint64_t foo(uint32_t x, uint64_t y) { return x*y; }
      Такие кросотки нужно инлайнить.
      Ответить
      • Мне кажется, что этот код был создан строго для эксперимента.
        Ответить
    • Вот и задумаешься -- следует-ли лишнюю функцию плодить
      Ответить
    • как-то дофига операций для умножения
      Ответить
      • Вы, похоже не заметили, что это умножение 64-битной переменной, на 32-битную используя 32-битные операции. ;)
        Ответить
        • сори ошибся
          Ответить
        • а ещё дя х86 сдецтва асм не люблю. Чтоб не маркетологи - могла бы быть нормальная архитектура. А то не каждый микроконтроллер может похвастаться такой контуженностью как IA
          Ответить
    • Кстати говоря, gcc4.4.4 дал следующий код:
      xaionaro@bellatrix:~$ gcc -c -O2 t3.c
      xaionaro@bellatrix:~$ objdump -d t3.o
      
      t3.o:     file format elf32-i386
      
      
      Disassembly of section .text:
      
      00000000 <foo>:
         0:   55                      push   %ebp
         1:   89 e5                   mov    %esp,%ebp
         3:   8b 45 08                mov    0x8(%ebp),%eax
         6:   8b 4d 10                mov    0x10(%ebp),%ecx
         9:   0f af c8                imul   %eax,%ecx
         c:   f7 65 0c                mull   0xc(%ebp)
         f:   5d                      pop    %ebp
        10:   8d 14 11                lea    (%ecx,%edx,1),%edx
        13:   c3                      ret
      Ответить
    • показать все, что скрытоГде здесь Haskell?
      Ответить
    • Да, вроде как сейчас только для сложной адресации lea выгоднее, чем add/sub - больше латентность, хуже "спаривается". Зато она флаги не меняет.;) x86 асм рулит - если осилишь...
      Ответить
    • Ебануться. Процессоры в нормальное умножение не умеют?
      Ответить

    Добавить комментарий