Сборный / Говнокод #3500 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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 3.14159265, (Updated )

Комментарии (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-))
    Ответить
        • у меня есть отличный поне, но он для 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,.
            Ответить
  • Дятел, ты хоть сотую часть GCC оптимизатора осиль понять, а потом будешь тут свои "находки из трюма" выкладывать.
    Гений, робана ёт, оптимизаций.
    Ответить
    • зачем мне их осиливать??
      если он генит такие вещи?
      mov [esp], ebx
      mov ebx, [esp]

      собственно тут проскакивало, что типа MS - кал. из-за таких вещей
      fistp qword [tmp]
      fild qword [tmp]

      юзайте gcc. а оказывается и у 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
                            Ответить
  • >;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
    Ответить
  • Да, вроде как сейчас только для сложной адресации lea выгоднее, чем add/sub - больше латентность, хуже "спаривается". Зато она флаги не меняет.;) x86 асм рулит - если осилишь...
    Ответить
  • Ебануться. Процессоры в нормальное умножение не умеют?
    Ответить

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

Семь раз отмерь — один отрежь, guest!

    А не использовать ли нам bbcode?


    8