Ассемблерный код работает медленнее сишного!

Тема в разделе "WASM.A&O", создана пользователем Adrax, 30 сен 2007.

  1. AndNot

    AndNot New Member

    Публикаций:
    0
    Регистрация:
    7 янв 2007
    Сообщения:
    49
    Эк тя расколбасило :lool:
    Вполне достаточно, чтобы обогнать третий вариант, от Adrax :P
    Бред :\
    Еще раз бред. Увеличение работы с памятью не может добавить прироста.
     
  2. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    А я бы согласился. Это по опыту своему скромному работы с msvc 8.
     
  3. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    AndNot

    Слушай, идиот, не упоминай при мне слово бред.

    Я понимаю, что для кулхацкеров неочевидна разница между movzx и mov , поэтому прежде чем писать такую [...], как "Увеличение работы с памятью", сначала попробуй, а потом будешь делать заявления.
     
  4. AndNot

    AndNot New Member

    Публикаций:
    0
    Регистрация:
    7 янв 2007
    Сообщения:
    49
    to Cresta[/]
    Во первых. Я тебя где нибудь обзывал?
    Во вторых. Прежде чем что то называть [...], сам бы проверил, после этого ты бы так не говорил. Подумай о промахах кэша и как это скажется на производительности.
    В третьих. Я не говорил, что VC создает плохой код, я утверждаю что человек сделает лучше. Можем и проверить, только на более жизненных примерах, например альфа-наложение.
    И в четвертых. Если не нравится мой словарный запас, то составь список слов, которые можно употреблять в твоем присутствии. :-?
     
  5. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    ИМХО для большого N:
    надо было взять код на С,
    проинициализировать array[] где надо нулями,
    внутренний цикл расписать на несколько переменных а внешний сократить во столько же раз,
    и откомпилировать gcc версии не ниже 4.1.x c опциями на максимальную оптимизацию.

    P.S. или для начала откомпилировать разными компиляторами и посмотреть
     
  6. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    2 t00x
    Сейчас попробую gcc, спасибо за идею

    Насчёт использования либ... Скачал я GMP в исходниках, функи из mpn с аттшного синтаксиса на родной интеловский перевёл - а дальше ступор...
    Типы данных там очччень прикольно описаны:
    Функция принимает параметры типа x. Тип x описан в таком-то хедере, как массив переменных типа y количеством z. За y и z нужно лезть в другие хедеры, потом ещё и ещё...
     
  7. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Код, который работает в 3 раза быстрее самого быстрого из приведенных выше в этом топике
    С использованием reciprocal division.

    Код (Text):
    1. .data
    2. align 16
    3.     Len   dd  1  
    4. align 16    
    5.     array dw  1
    6.           dw  1000000 dup(0)
    7.  
    8.  
    9. ;--------------------------------------------------
    10. factorial proc N:DWORD
    11.     option prologue : none
    12.     option epilogue : none
    13.             push    ebp
    14.             push    edi
    15.             push    esi
    16.             push    ebx
    17.             xor     ecx,ecx
    18.             mov     ebx,1
    19.             cmp     dword ptr [esp+20],1
    20.             mov     esi,Len
    21.             mov     ebp,3518437209
    22.             jb      _end
    23.         _ext:
    24.             xor     edi,edi
    25.        align 16
    26.         _int:    
    27.             movzx   eax,word ptr[array+edi*2]
    28.             imul    eax,ebx
    29.             add     ecx,eax
    30.             mov     eax,ecx
    31.             mul     ebp
    32.             shr     edx,13
    33.             imul    eax,edx,10000
    34.             sub     ecx,eax
    35.             mov     word ptr[array+edi*2],cx
    36.             inc     edi
    37.             mov     ecx,edx
    38.             cmp     edi,esi
    39.             jc      _int
    40.             test    edx,edx
    41.             jnz     _int
    42.             inc     ebx
    43.             mov     esi,edi
    44.             cmp     [esp+20],ebx
    45.             jnc     _ext
    46.             mov     Len,edi
    47.            
    48.         _end:    
    49.             pop     ebx
    50.             pop     esi
    51.             pop     edi
    52.             pop     ebp
    53.             retn    4      
    54.                                
    55.     option prologue : prologuedef
    56.     option epilogue : epiloguedef
    57. factorial endp
    Сравнение производилось на Athlon XP 2200+
     
  8. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    2 cresta

    Преклоняюсь перед Вашим мастерством!!!
    Уму непостижимо! 150000! за 1:16!!!
    Ваш код божественен!!!

    В начале темы я утратил веру в Ассемблер, но Вы вернули мне её!!!

    Нет слов...
    Объясните мне, как Вы этого добились?! Дайте хоть ссылочку на основы этого reciprocal division!
     
  9. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    Ээээ... Сворачиваю своё восхищённое словоизвержение...
    Код cresta я впихнул отдельной процедурой, вот так:
    Код (Text):
    1. format PE console
    2. include 'win32axp.inc'
    3. .data
    4.         dllka db 'msvcrt.dll',0
    5.         name1 db 'scanf',0
    6.         scanf dd ?
    7.         name2 db 'printf',0
    8.         printf dd ?
    9.         inp db 'Input N:',0
    10.         d db '%d',0
    11.         d4 db '%04d',0
    12.         crlf db 13,10,0
    13.         N dd ?
    14.  
    15.         align 16
    16.         Len dd 1
    17.  
    18.         align 16
    19.         array dw 1
    20.               dw 999999 dup 0
    21.  
    22. .code
    23. fuck:
    24.         invoke LoadLibrary,dllka
    25.         push eax
    26.         invoke GetProcAddress,eax,name1
    27.         mov [scanf],eax
    28.         pop eax
    29.         invoke GetProcAddress,eax,name2
    30.         mov [printf],eax
    31.         cinvoke printf,inp
    32.         cinvoke scanf,d,N
    33.  
    34.         mov eax,[N]
    35.         test eax,eax
    36.         jl konets
    37.  
    38.         push eax
    39.         call Factorial
    40.         call Printt
    41.  
    42.  
    43.  
    44.  
    45. konets:
    46.         cinvoke printf,crlf
    47.         invoke ExitProcess,0
    48. ;-----------------------------------------------------
    49.       proc Factorial
    50.         push ebp
    51.         push edi
    52.         push esi
    53.         push ebx
    54.         xor ecx,ecx
    55.         mov ebx,1
    56.         cmp dword[esp+20],1
    57.         mov esi,[Len]
    58.         mov ebp,3518437209
    59.         jb _end
    60.  
    61.                 _ext:
    62.                      xor edi,edi
    63.                 align 16
    64.                 _int:
    65.                      movzx eax,word[array+edi*2]
    66.                      imul eax,ebx
    67.                      add ecx,eax
    68.                      mov eax,ecx
    69.                      mul ebp
    70.                      shr edx,13
    71.                      imul eax,edx,2710h
    72.                      sub ecx,eax
    73.                      mov word[array+edi*2],cx
    74.                      inc edi
    75.                      mov ecx,edx
    76.                      cmp edi,esi
    77.                      jc _int
    78.                      test edx,edx
    79.                      jnz _int
    80.                      inc ebx
    81.                      mov esi,edi
    82.                      cmp dword[esp+20],ebx
    83.                      jnc _ext
    84.                      mov [Len],edi
    85.       _end:
    86.            pop ebx
    87.            pop esi
    88.            pop edi
    89.            pop ebp
    90.            retn 4
    91.            endp
    92. ;--------------------------------------------------
    93.     proc Printt
    94.         mov edi,[Len]
    95.         movzx eax,word [array-2+edi*2]
    96.         cinvoke printf,d,eax
    97.         dec edi
    98.         jz konets
    99.  
    100.       mtk:
    101.         dec edi
    102.         movzx ecx,word[array+edi*2]
    103.         cinvoke printf,d4,ecx
    104.         test edi,edi
    105.         jnz mtk
    106.         retn
    107.         endp
    108. ;-------------------------------------------------
    109. .end fuck
    Быстро, слов нет... Но для любого N>7 получается искажённый результат N!
    Так что вопрос снова поднят...
    Есть ли более быстрые варианты ПРАВИЛЬНОГО вычисления факториала?
     
  10. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    для N=10 результат верен ;)
     
  11. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    А для N=1000 у N! несколько лишних разрядов:)