Nil Satis Nisi Optimum - Logoszféra fórum

üzenetek

hozzászólások

(#21) P.H.


    P.H.
    (senior tag)

    SSE2-kód AMD-re egy kicsit kevesebb utasítással, kis utasítássorrend-módosítással (körvonalazódik, hogy VectorPath célszerűen feltételes ugrás után vagy ugrás céljaként rendezendő)

    K8 Opteron: 517M clock (-10%), átlagosan 1.3 IPC

    @copyarraySSE:
    movd xmm0,[eax+04h]
    @zoomvertSSE:
    mov [esp],edi
    xor ebx,ebx
    mov esi,[esp+_STRROWS]
    and edi,-64
    sub edx,[esp+_STRLEFT]
    movd ebp,mm7
    pshufd xmm0,xmm0,00000000b
    movd ecx,mm6
    lea edi,[edi+40h]
    mov esi,[esi]
    cmovge edx,ebx
    movaps xmm1,[edi]
    @sourceLEFT:
    mov bl,[esi]
    add esi,02h
    add edx,ebx
    jle @sourceLEFT
    mov bl,[esi-01h]
    jmp @initpixelSSE
    @newpixelSSE:
    movzx edx,word ptr [esi]
    add esi,02h
    movzx ebx,dh
    @initpixelSSE:
    movaps xmm3,xmm0
    shl ebx,04h
    add dl,01h
    add ebx,[esp+_STRCOLORS]
    mulps xmm3,[ebx]
    @prevHpixelSSE:
    sub dl,01h
    jz @newpixelSSE
    pshufd xmm2,[ecx+00h],10010101b
    movaps xmm4,xmm3
    mov ebx,[ecx+00h]
    @pixelSSE:
    mulps xmm4,xmm2
    sub ebx,01h
    @1pixelSSE:
    addps xmm1,xmm4
    jz @nextHpixelSSE
    movaps [edi],xmm1
    js @stepHelementSSE
    add edi,10h
    movaps xmm4,xmm3
    sub ebx,01h
    movaps xmm1,[edi]
    jnz @1pixelSSE
    @nextHpixelSSE:
    pshufd xmm2,xmm2,11111111b
    cmp ebx,[ecx+08h]
    jnz @pixelSSE
    not ebx
    @stepHelementSSE:
    add ebp,ebx
    lea ecx,[ecx+10h]
    jnz @prevHpixelSSE
    mov edi,[esp]
    xor edx,edx
    @moreVrowsSSE:
    add [eax+00h],ebx
    jg @cvtROW
    jl @stepVelementSSE
    add ebp,[eax+08h]
    movd xmm0,ebp
    jnz @zoomvertSSE
    @stepVelementSSE:
    add dword ptr [esp+_STRROWS],04h
    add [esp+_VSIZE],ebx
    lea eax,[eax+10h]
    jnz @copyarraySSE
    sub eax,10h
    mov [eax+00h],ebx
    @cvtROW:
    mov esi,edi
    mov ebp,[esp+_INCREASE]
    and esi,-64
    sub edi,ebp
    @cvtRGB:
    add esi,40h
    cvtps2dq xmm1,[esi+00h]
    cvtps2dq xmm2,[esi+10h]
    cvtps2dq xmm3,[esi+20h]
    cvtps2dq xmm4,[esi+30h]
    movaps [esi+00h],xmm5
    packssdw xmm1,xmm2
    movaps [esi+10h],xmm5
    packssdw xmm3,xmm4
    movaps [esi+20h],xmm5
    packuswb xmm1,xmm3
    movaps [esi+30h],xmm5
    movups [edi+ebp],xmm1
    add ebp,10h
    js @cvtRGB
    cmp dword ptr [eax+00h],01h
    jz @moreVrowsSSE
    divss xmm0,xmm0
    jg @zoomvertSSE

    [ Szerkesztve ]

    (#22) P.H.


      P.H.
      (senior tag)

      Valamiért a K8 is jobban szereti, ha az utasítások konstans paramétere nem azonnali érték, hanem regiszter, az előforduló függőségek ellenére is; talán az utasításhossz-csökkenés miatt? (a Netburst-ön még jobban kijön a plusz, ennek a trace-cache felépítése lehet az oka)

      K8-on még 1% van benne, egy-egy felesleges, de csak ritkán lefutó utasítás eltávolításával és egy ugráscél áthelyezésével: 513M clock

      gépi kód:

      @copyarraySSE:
      movd xmm0,[eax+04h] 660F6E4004
      @zoomvertSSE:
      mov [esp],edi 893C24
      xor ebx,ebx 31DB
      mov esi,[esp+_STRROWS] 8B74242C
      and edi,-64 83E7C0
      sub edx,[esp+_STRLEFT] 2B542430
      movd ebp,mm7 0F7EFD
      pshufd xmm0,xmm0,00000000b 660F70C000
      movd ecx,mm6 0F7EF1
      lea edi,[edi+40h] 8D7F40
      mov esi,[esi] 8B36
      cmovge edx,ebx 0F4DD3
      movaps xmm1,[edi] 0F280F
      @sourceLEFT:
      mov bl,[esi] 8A1E
      add esi,02h 83C602
      add edx,ebx 01DA
      jle @sourceLEFT 7EF7
      mov bl,[esi-01h] 8A5EFF
      jmp @initpixelSSE EB09
      @newpixelSSE:
      movzx edx,word ptr [esi] 0FB716
      add esi,02h 83C602
      movzx ebx,dh 0FB6DE
      @initpixelSSE:
      movaps xmm3,xmm0 0F28D8
      shl ebx,04h C1E304
      add ebx,[esp+_STRCOLORS] 035C2428
      mulps xmm3,[ebx] 0F591B
      @prevHpixelSSE:
      sub dl,01h 80EA01
      jc @newpixelSSE 72E5
      pshufd xmm2,[ecx+00h],10010101b 660F701195
      movaps xmm4,xmm3 0F28E3
      mov ebx,[ecx+00h] 8B19
      @pixelSSE:
      mulps xmm4,xmm2 0E59E2
      sub ebx,01h 83EB01
      @1pixelSSE:
      addps xmm1,xmm4 0F58CC
      jz @nextHpixelSSE 7413
      movaps [edi],xmm1 0F290F
      js @stepHelementSSE 781A
      add edi,10h 83C710
      movaps xmm4,xmm3 0F28E3
      sub ebx,01h 83EB01
      movaps xmm1,[edi] 0F280F
      jnz @1pixelSSE 75E8
      @nextHpixelSSE:
      pshufd xmm2,xmm2,11111111b 660F70D2FF
      cmp ebx,[ecx+08h] 3B5908
      jnz @pixelSSE 75D8
      not ebx F7D3
      @stepHelementSSE:
      add ebp,ebx 01DD
      lea ecx,[ecx+10h] 8D4910
      jnz @prevHpixelSSE 75C0
      mov edi,[esp] 8B3C24
      xor edx,edx 31D2
      add [eax+00h],ebx 0118
      jg @cvtROW 7F26
      jl @stepVelementSSE 7C0F
      @moreVrowsSSE:
      mov [eax+00h],edx 8910
      add ebp,[eax+08h] 036808
      movd xmm0,ebp 660F6EC5
      jnz @zoomvertSSE 0F855CFFFFFF
      @stepVelementSSE:
      add dword ptr [esp+_STRROWS],04h 8344244C04
      add [esp+_VSIZE],ebx 015C2414
      lea eax,[eax+10h] 8D4010
      jnz @copyarraySSE 0F8545FFFFFF
      sub eax,10h 83E810
      @cvtROW:
      mov esi,edi 89FE
      mov ebp,[esp+_INCREASE] 8B6C2418
      and esi,-64 83E6C0
      sub edi,ebp 29EF
      @cvtRGB:
      add esi,40h 83C640
      cvtps2dq xmm1,[esi+00h] 660F5B0E
      cvtps2dq xmm2,[esi+10h] 660F5B5610
      cvtps2dq xmm3,[esi+20h] 660F5B5E20
      cvtps2dq xmm4,[esi+30h] 660F5B6630
      movaps [esi+00h],xmm5 0F290E
      packssdw xmm1,xmm2 660F6BC6
      movaps [esi+10h],xmm5 0F296E10
      packssdw xmm3,xmm4 660F0BCD
      movaps [esi+20h],xmm5 0F296E20
      packuswb xmm1,xmm3 660F67CB
      movaps [esi+30h],xmm5 0F296E30
      movups [edi+ebp],xmm1 0F110C2F
      add ebp,10h 83C510
      js @cvtRGB 78C6
      add ebx,[eax+00h] 0318
      jz @moreVrowsSSE 7493
      divss xmm0,xmm0 F30F5EC0
      jg @zoomvertSSE 0F8FF4FEFFFF

      [ Szerkesztve ]

      (#23) P.H.


        P.H.
        (senior tag)

        Többszálú pufferkezelési kód. Lehetne jobb is... (?)

        function _WAITTHREADS: DWORD;
        asm test eax,eax
        pushad
        mov ebx,esp
        jz @return
        xor ebp,ebp
        @threadarray:
        shr eax,01h
        lea edx,[edx+TBUFFERSIZE]
        jnc @threadarray
        lea ebp,[ebp+01h]
        push dword ptr [edx+TBUFFER.THREAD]
        jnz @threadarray
        mov edx,esp
        push INFINITE; push ecx; push edx; push ebp; call WINDOWS.WAITFORMULTIPLEOBJECTS
        mov esp,ebx
        @return:
        popad
        test eax,eax end;
        procedure _RESTARTBUFFERS;
        asm pushad
        mov edx,offset(BUFFERS)
        mov bl,cBUFFER
        xor ebp,ebp
        mov eax,[PENDINGS]; mov ecx,01h; sub edx,TBUFFERSIZE; call _WAITTHREADS
        mov esi,edx
        mov edi,eax
        @init:
        sub bl,cl
        lea esi,[esi+TBUFFERSIZE]
        js @return
        shr edi,cl
        jc @init
        mov edx,esi; call _BUF0
        jmp @init
        @return:
        mov [PENDINGS],ebp
        mov [LOCKBITS],ebp
        popad end;
        procedure _ZEROBUFFER(Blank,Buffer:pointer);
        asm cmp byte ptr [_INSSET+__CPUS],01h
        mov ecx,[edx+TBUFFER.BIT]
        ja @moreCPU
        xor ecx,-1
        and [LOCKBITS],ecx
        jmp _BUF0
        @moreCPU:
        push ebx
        lea ebx,[edx+TBUFFER.THREAD]
        lock or [PENDINGS],ecx
        push ebx; push 00h; push edx; push offset(@ZTHREAD); push 60h; push 00h; call CREATETHREAD
        mov [ebx],eax
        pop ebx
        ret
        @ZTHREAD:
        { ESP+04h: TBUFFER structure
        mov edx,[esp+04h]
        or ecx,-1
        xor ecx,[edx+TBUFFER.BIT]
        call _BUF0
        lock and [LOCKBITS],ecx
        lock and [PENDINGS],ecx
        ret 04h end;
        procedure _FREEBUFFER(Value:pHGLOBAL);
        asm mov edx,eax
        xor ecx,ecx
        mov eax,[eax]
        mov [edx],ecx
        test eax,eax
        mov edx,offset(BUFFERS)
        jz @return
        @search:
        cmp eax,[edx+TBUFFER.ADDR]
        jz _ZEROBUFFER
        add ecx,01h
        add edx,TBUFFERSIZE
        cmp ecx,cBUFFER
        jb @search
        mov eax,[_NOFREE]
        jmp ERRORFORM
        @return: end;
        function _GETBUFFER(Dest:pHGLOBAL): HGLOBAL;
        asm pushad
        mov esi,offset(BUFFERS)
        mov edi,_hINV
        sub esi,TBUFFERSIZE
        @testbuffers:
        mov ebp,[LOCKBITS]
        mov ebx,00000001h
        mov edx,esi
        mov cl,cBUFFER
        mov eax,[PENDINGS]
        @search:
        test ebp,ebx
        lea edx,[edx+TBUFFERSIZE]
        jz @lock
        sub cl,01h
        lea ebx,[ebx+ebx]
        jg @search
        xor ecx,ecx; call _WAITTHREADS
        jnz @testbuffers
        popad
        mov eax,[_NOGET]; call ERRORFORM
        xor eax,eax
        ret
        @lock:
        mov esi,[esp+_EAX]
        mov eax,[edx+TBUFFER.ADDR]
        mov ecx,[edx+TBUFFER.THREAD]
        mov [edx+TBUFFER.THREAD],edi
        mov [esi],eax
        lock or [LOCKBITS],ebx
        push ecx; call WINDOWS.CLOSEHANDLE
        popad
        mov eax,[eax] end;

        [ Szerkesztve ]

        (#24) P.H.


          P.H.
          (senior tag)

          Pufferenként 1-1 előre elindított végtelenített szál + pufferenként 2 event:
          - Erase: automatikusan resetelt, 0 kezdőértékkel
          - Ready: kézileg resetelt, 0 kezdőértékkel

          procedure _ZTHREAD;
          { [ESP+04h]: TBUFFER address
          asm mov edx,[esp+04h]
          pushad
          mov edi,[edx+TBUFFER.BIT]
          mov esi,edx
          mov ebp,[edx+TBUFFER.ERASE]
          mov ebx,offset(BUFFERS)
          xor edi,-1
          @loop:
          push INFINITE; push ebp; call WINDOWS.WAITFORSINGLEOBJECT
          mov eax,[esi+TBUFFER.ADDR]; mov edx,[esi+TBUFFER.SIZE]; call _ZEROMEM
          push dword ptr [esi+TBUFFER.READY]; call WINDOWS.SETEVENT
          lock and [ebx+_LOCKBITS],edi
          lock and [ebx+_PENDINGS],edi
          jmp @loop
          popad
          ret 04h end;
          procedure _FREEBUFFER(Value:pHGLOBAL);
          asm mov edx,eax
          xor ecx,ecx
          mov eax,[eax]
          mov [edx],ecx
          mov cl,cBUFFER
          test eax,eax
          mov edx,offset(BUFFERS)
          jz @return
          @search:
          sub cl,01h
          lea edx,[edx+TBUFFERSIZE]
          js @error
          cmp eax,[edx+TBUFFER.ADDR]
          jnz @search
          @freebuffer:
          cmp byte ptr [_INSSET+__CPUs],01h
          mov ecx,[edx+TBUFFER.BIT]
          jbe @oneCPU
          lock or dword ptr [BUFFERS+_PENDINGS],ecx
          push dword ptr [edx+TBUFFER.ERASE]; call WINDOWS.SETEVENT
          ret
          @oneCPU:
          xor ecx,-1
          mov eax,[edx+TBUFFER.ADDR]; mov edx,[edx+TBUFFER.SIZE]
          and dword ptr [BUFFERS+_LOCKBITS],ecx
          jmp _ZEROMEM
          @error:
          mov eax,[_NOFREE]
          jmp ERRORFORM
          @return: end;
          procedure _RESTARTBUFFERS;
          asm pushad
          mov edx,offset(BUFFERS); or ecx,-1
          xor edi,edi
          mov eax,[edx+_PENDINGS]; call _WAITFORBUFFER
          mov esi,edx
          mov ebp,[edx+_LOCKBITS]
          mov bl,cBUFFER
          mov [edx+_LOCKBITS],edi
          mov [edx+_PENDINGS],edi
          add edi,01h
          @search:
          sub bl,01h
          lea esi,[esi+TBUFFERSIZE]
          js @return
          test ebp,edi
          lea edi,[edi+edi]
          jz @search
          mov eax,[esi+TBUFFER.ADDR]; mov edx,[esi+TBUFFER.SIZE]; call _ZEROMEM
          jmp @search
          @return:
          popad end;
          function _WAITFORBUFFER: DWORD;
          asm test eax,eax
          pushad
          mov edi,ecx
          mov ebx,esp
          jz @return
          xor ebp,ebp
          @threadarray:
          shr eax,01h
          lea edx,[edx+TBUFFERSIZE]
          jnc @threadarray
          lea ebp,[ebp+01h]
          push dword ptr [edx+TBUFFER.READY]
          jnz @threadarray
          mov edx,esp
          push INFINITE; push edi; push edx; push ebp; call WINDOWS.WAITFORMULTIPLEOBJECTS
          mov esp,ebx
          @return:
          popad
          test eax,eax end;
          function _GETBUFFER(Dest:pHGLOBAL): HGLOBAL;
          asm pushad
          mov esi,offset(BUFFERS)
          mov edi,eax
          @testbuffers:
          mov ebp,[esi+_LOCKBITS]
          mov ebx,00000001h
          mov edx,esi
          mov cl,cBUFFER
          mov eax,[esi+_PENDINGS]
          @search:
          test ebp,ebx
          lea esi,[esi+TBUFFERSIZE]
          jz @lock
          sub cl,01h
          lea ebx,[ebx+ebx]
          jg @search
          cmp ebp,[edx+_LOCKBITS]
          mov esi,edx
          jnz @testbuffers
          xor ecx,ecx; call _WAITFORBUFFER
          jnz @testbuffers
          @error:
          mov eax,[_NOGET]; call ERRORFORM
          xor ebx,ebx
          mov edx,esi
          @lock:
          mov eax,[esi+TBUFFER.ADDR]
          lock or [edx+_LOCKBITS],ebx
          mov [edi],eax
          push dword ptr [esi+TBUFFER.READY]; call WINDOWS.RESETEVENT
          popad
          mov eax,[eax] end;

          [ Szerkesztve ]

          (#25) P.H.


            P.H.
            (senior tag)

            Közismert és általános algoritmushoz tartozó kód legalább 6-7 éve és ma

            Első rész, a főciklus előtti inicializációs részek:

            Régen:
            mov ecx,[MTXDBLSIZE]
            mov edi,[MARKS]
            xor eax,eax
            mov ebp,[MTXSIZE]
            mov edx,ecx
            rep stosd
            lea edi,[tempmarks]
            mov ecx,edx
            rep stosd

            @reduce_rows_with_minimum:
            mov edi,[mtx]
            mov edx,ebp
            mov esi,00FFFFFFh
            @row_minimum:
            mov ecx,ebp
            mov ebx,edi
            mov eax,esi
            mov ch,cl
            @find_row_minimum:
            scasd
            jb @after_row_test
            mov eax,[edi-04h]
            @after_row_test:
            dec cl
            jnz @find_row_minimum
            @start_reduce_row:
            test eax,eax
            jnz @force_reduce_row
            dec edx
            jnz @row_minimum
            jmp @reduce_columns_with_minimum
            @force_reduce_row:
            cmp eax,esi
            jz @abnormal_exit
            @reduce_row_elements:
            cmp [ebx],esi
            ja @after_row_reduction
            sub [ebx],eax
            @after_row_reduction:
            add ebx,04h
            dec ch
            jnz @reduce_row_elements
            dec edx
            jnz @row_minimum

            @reduce_columns_with_minimum:
            mov esi,[mtx]
            mov ebx,ebp
            lea edi,[ebp*04h]
            @column_minimum:
            mov ecx,ebp
            mov eax,00FFFFFFh
            mov edx,esi
            mov ch,cl
            @find_column_minimum:
            cmp [esi],eax
            ja @after_column_test
            mov eax,[esi]
            test eax,eax
            jz @next_decrease_column
            @after_column_test:
            add esi,edi
            dec cl
            jnz @find_column_minimum
            @start_reduce_column:
            cmp eax,00FFFFFFh
            jz @abnormal_exit
            mov esi,edx
            @reduce_column_elements:
            cmp dword ptr [esi],00FFFFFFh
            ja @after_column_reduction
            sub [esi],eax
            @after_column_reduction:
            add esi,edi
            dec ch
            jnz @reduce_column_elements
            @next_decrease_column:
            lea esi,[edx+04h]
            dec ebx
            jnz @column_minimum

            @determine_start0_system:
            mov [sys0],ebx
            mov edi,[marks]
            mov ebx,ebp
            mov eax,0102h
            mov esi,[mtx]
            xor ecx,ecx
            dec ebx
            push esi
            xor edx,edx
            @start_0system:
            lea esi,[esi+ebx*04h]
            @find_free0:
            test [edi+edx],al
            jnz @check_next_item
            cmp [esi],ecx
            jnz @check_next_item
            or [edi+edx],al
            or [edi+ebx],ah
            or [esi+03h],ah
            inc [sys0]
            jmp @next_column
            @check_next_item:
            inc edx
            lea esi,[esi+ebp*04h]
            cmp edx,ebp
            jnz @find_free0
            @next_column:
            mov esi,[esp]
            xor edx,edx
            dec ebx
            jns @start_0system
            pop ebx

            cmp ebp,[sys0]
            jz @count_result
            mov eax,01010101h
            mov ecx,[MTXDBLSIZE]
            @clearrowmark:
            and [edi],eax
            sub ecx,01h
            lea edi,[edi+04h]
            jnz @clearrowmark
            pushad
            jmp @@2nd_step

            Mai termés (kb. 10% gyorsulás a teljes lefutásra vetítve)
            mov ebp,[MTXSIZE]
            @reduce_rows_with_minimum:
            mov esi,00FFFFFFh
            mov edi,[MTX]
            mov edx,ebp
            @rowmin:
            mov eax,esi
            mov ebx,edi
            mov ecx,ebp
            @findrowmin:
            cmp eax,[ebx]
            jb @nxrowmin
            mov eax,[ebx]
            @nxrowmin:
            sub ecx,01h
            lea ebx,[ebx+04h]
            jnz @findrowmin
            cmp eax,esi
            mov ecx,ebp
            jz @abnormal_exit
            @decrow:
            cmp [edi],esi
            sbb ebx,ebx
            and ebx,eax
            sub [edi],ebx
            sub ecx,01h
            lea edi,[edi+04h]
            jnz @decrow
            sub edx,01h
            jnz @rowmin

            @reduce_columns_with_minimum:
            mov ebx,ebp
            shl ebp,02h
            mov edi,[MTX]
            @colmin:
            mov ecx,ebp
            mov eax,esi
            @findcolmin:
            cmp [edi],eax
            ja @nxcolmin
            mov eax,[edi]
            @nxcolmin:
            sub ecx,04h
            lea edi,[edi+ebp]
            jnz @findcolmin
            neg ebp
            cmp eax,esi
            mov ecx,ebp
            jz @abnormal_exit
            @deccol:
            add edi,ebp
            cmp [edi],esi
            sbb edx,edx
            and edx,eax
            sub [edi],edx
            add ecx,04h
            jnz @deccol
            neg ebp
            sub ebx,01h
            lea edi,[edi+04h]
            jnz @colmin
            shr ebp,02h

            imul ecx,[MTXDBLSIZE],BYTE(4)
            xor eax,eax
            mov edi,[MARKS]
            mov edx,offset(TEMPMARKS)
            mov esi,[MTX]
            @clrmark:
            sub ecx,04h
            mov [edi+ecx],eax
            mov [edx+ecx],eax
            jg @clrmark

            @determine_start0_system:
            lea ebx,[ebp-01h]
            add eax,01h
            push esi
            @start0system:
            lea esi,[esi+ebx*04h]
            xor edx,edx
            @findfree0:
            cmp dword ptr [esi],00h
            jz @markitem
            @nxrow:
            add edx,eax
            lea esi,[esi+ebp*04h]
            cmp edx,ebp
            jnz @findfree0
            jmp @nxcol
            @markitem:
            bts [edi+edx],eax
            jc @nxrow
            or [edi+ebx],al
            add ecx,eax
            or [esi+03h],al
            @nxcol:
            sub ebx,eax
            mov esi,[esp]
            jns @start0system
            pop ebx
            mov [SYS0],ecx

            cmp ebp,ecx
            mov eax,01010101h
            jz @count_result
            mov ecx,[MTXDBLSIZE]
            @clearrowmark:
            and [edi],eax
            sub ecx,01h
            lea edi,[edi+04h]
            jnz @clearrowmark
            pushad
            jmp @@2nd_step

            [ Szerkesztve ]

            (#26) P.H.


              P.H.
              (senior tag)

              Magyar módszer, legfejlebb 126x126-os mátrixokra, a mátrixelemek nagysága legfeljebb 00FFFFFFh. A sebességkülönbség kb. 3-szoros az új kód javára úgy, hogy a mátrix teljesen belefér (és belefért régen is) az L1D-be.

              Jelenlegi kód:
              pushad
              @@REDUCE_ROWS:
              mov esi,00FFFFFFh
              mov edi,eax
              mov edx,ebp
              @rowmin:
              mov eax,esi
              mov ebx,edi
              mov ecx,ebp
              @findrowmin:
              cmp eax,[edi]
              cmova eax,[edi]
              sub ecx,01h
              lea edi,[edi+04h]
              jnz @findrowmin
              cmp eax,esi
              mov ecx,ebp
              jz @@ABNORMAL_EXIT
              @decrow:
              xor edi,edi
              cmp [ebx],esi
              cmovbe edi,eax
              sub [ebx],edi
              sub ecx,01h
              lea ebx,[ebx+04h]
              jnz @decrow
              sub edx,01h
              mov edi,ebx
              jnz @rowmin
              jmp @@REDUCE_COLUMNS
              @@ABNORMAL_EXIT:
              add esp,20h
              xor eax,eax
              mov edx,7FFFFFFFh
              stc
              ret
              @@REDUCE_COLUMNS:
              mov ebx,ebp
              mov edi,[esp+__MTX]
              @colmin:
              mov eax,esi
              mov ecx,ebp
              @findcolmin:
              cmp eax,[edi]
              cmova eax,[edi]
              sub ecx,01h
              lea edi,[edi+ebp*04h]
              jnz @findcolmin
              neg ebp
              cmp eax,esi
              mov ecx,ebp
              jz @@ABNORMAL_EXIT
              @deccol:
              lea edi,[edi+ebp*04]
              xor edx,edx
              cmp [edi],esi
              cmovbe edx,eax
              sub [edi],edx
              add ecx,01h
              jnz @deccol
              neg ebp
              sub ebx,01h
              lea edi,[edi+04h]
              jnz @colmin
              @@INITMARKS:
              mov ebx,offset(MARKS)
              lea ecx,[ebp+ebp]
              xor eax,eax
              lea edi,[ebx+ebp]
              mov esi,[esp+__MTX]
              @clrmark:
              sub ecx,04h
              mov [ebx],eax
              lea ebx,[ebx+04h]
              jg @clrmark
              @@START0_SYSTEM:
              xor ebx,ebx
              lea esi,[esi+ebp*04h]
              add eax,01h
              xor ecx,ecx
              @start0system:
              sub esi,04h
              xor edx,edx
              sub ebx,eax
              push esi
              sub edx,ebp
              @findfree0:
              cmp [esi],eax
              jb @markitem
              @nxrow:
              add edx,eax
              lea esi,[esi+ebp*04h]
              jnz @findfree0
              jmp @nxcol
              @markitem:
              bts dword ptr [edi+edx],01h
              jc @nxrow
              add edx,ebp
              mov [esi+03h],al
              add ecx,eax
              mov [edi+edx],bl
              or [edi+ebx],al
              @nxcol:
              lea edx,[ebx+ebp]
              pop esi
              test edx,edx
              jnz @start0system
              mov [esp+__SYS0],ecx
              @@CLEARROWMARKS:
              cmp ebp,ecx
              jz @count_result_MTX
              @clear_row_mark:
              and [edi+ebx],al
              add ebx,eax
              jnz @clear_row_mark
              sub esp,_SAVE
              jmp @@2ND_STEP
              @@3RD_STEP:
              mov byte ptr [esi+03h],02h
              and byte ptr [edi+edx],11111110b
              @@2ND_STEP:
              xor ebx,ebx
              mov esi,[esp+_SAVE+__MTX]
              xor ecx,ecx
              mov edx,00FFFFFFh
              sub ebx,ebp
              @free0:
              sub ecx,ebp
              @freerow:
              test byte ptr [edi+ebx],02h
              jz @zeroinrow
              add ebx,01h
              lea esi,[esi+ebp*04h]
              jnz @freerow
              jmp @@5TH_STEP
              @zeroinrow:
              test byte ptr [edi+ecx],01h
              jnz @handlecol
              cmp edx,[esi]
              jbe @handlecol
              mov edx,[esi]
              test edx,edx
              jz @@DECIDE_NEXT_STEP
              add esp,_SAVE
              pushad
              @handlecol:
              add ecx,01h
              lea esi,[esi+04h]
              jnz @zeroinrow
              add ebx,01h
              jnz @free0
              @@5TH_STEP:
              xor ecx,ecx
              mov esi,[esp+_SAVE+__MTX]
              sub ebx,ebp
              @nx5row:
              sub ecx,ebp
              test byte ptr [edi+ebx],02h
              jz @decrease_row_free
              @increase_double_markeds:
              mov al,[esi+03h]
              and al,11111100b
              bt dword ptr [edi+ecx],00h
              sbb al,00h
              sbb eax,eax
              and eax,edx
              add [esi],eax
              add ecx,01h
              lea esi,[esi+04h]
              jnz @increase_double_markeds
              jmp @step5row
              @decrease_row_free:
              bt dword ptr [edi+ecx],00h
              mov al,[esi+03h]
              adc al,00h
              mov eax,00000000h
              cmovz eax,edx
              sub [esi],eax
              add ecx,01h
              lea esi,[esi+04h]
              jnz @decrease_row_free
              @step5row:
              add ebx,01h
              jnz @nx5row
              popad
              sub esp,20h
              @@DECIDE_NEXT_STEP:
              mov edx,0FFFFFF00h
              lea eax,[ebx+ebp]
              or byte ptr [edi+ebx],02h
              add dl,[edi+eax]
              jnz @@3RD_STEP
              @@4TH_STEP:
              mov edx,[esp+_SAVE+__MTX]
              add dword ptr [esp+_SAVE+__SYS0],01h
              @0colon:
              mov [edi+eax],cl
              add ecx,ebp
              mov byte ptr [esi+03h],01h
              xor eax,eax
              lea esi,[edx+ecx*04h]
              shl ecx,02h
              sub eax,ebp
              @search_star_in_column:
              test byte ptr [esi+03h],01h
              jz @nxstar
              cmp eax,ebx
              jnz @0_star
              @nxstar:
              add eax,01h
              lea esi,[esi+ebp*04h]
              jnz @search_star_in_column
              jmp @@1ST_STEP
              @0_star:
              mov ebx,eax
              mov byte ptr [esi+03h],00h
              add eax,ebp
              sub esi,ecx
              xor ecx,ecx
              mov byte ptr [edi+eax],00h
              sub ecx,ebp
              @search_colon_in_row:
              test byte ptr [esi+03h],02h
              jnz @0colon
              add ecx,01h
              lea esi,[esi+04h]
              jnz @search_colon_in_row
              @error:
              nop
              @@1ST_STEP:
              cmp ebp,[esp+_SAVE+__SYS0]
              jz @count_result_STACK
              lea edx,[edx+ebp*04h]
              push ebp
              @remove_row_marks_set_cols:
              lea esi,[edx-04h]
              sub edi,01h
              xor bl,bl
              mov ecx,ebp
              sub edx,04h
              @chkstarmark:
              mov al,[esi+03h]
              and al,11111101b
              mov [esi+03h],al
              and al,01h
              or bl,al
              sub ecx,01h
              lea esi,[esi+ebp*04h]
              jnz @chkstarmark
              sub dword ptr [esp],01h
              mov [edi],bl
              jnz @remove_row_marks_set_cols
              pop ebx
              add edi,ebp
              jmp @@2ND_STEP
              @count_result_STACK:
              add esp,_SAVE
              @count_result_MTX:
              xor ecx,ecx
              xor eax,eax
              mov esi,[esp+__SAVE]
              mov ebx,[esp+__MARKS]
              @results:
              movsx edx,byte ptr [edi+ecx]
              mov byte ptr [edi+ecx],00h
              add ecx,01h
              add edx,ebp
              add eax,[esi+edx*04h]
              cmp ecx,ebp
              mov [ebx],dl
              lea esi,[esi+ebp*04h]
              lea ebx,[ebx+01h]
              jnz @results

              6-7 évvel ezelőtti kód:
              mov ecx,[mtxdblsize]
              mov edi,[marks]
              xor eax,eax
              mov ebp,[mtxsize]
              mov edx,ecx
              rep stosd
              lea edi,[tempmarks]
              mov ecx,edx
              rep stosd

              @reduce_rows_with_minimum:
              mov edi,[mtx]
              mov edx,ebp
              mov esi,00FFFFFFh
              @row_minimum:
              mov ecx,ebp
              mov ebx,edi
              mov eax,esi
              mov ch,cl
              @find_row_minimum:
              scasd
              jb @after_row_test
              mov eax,[edi-04h]
              @after_row_test:
              dec cl
              jnz @find_row_minimum
              @start_reduce_row:
              test eax,eax
              jnz @force_reduce_row
              dec edx
              jnz @row_minimum
              jmp @reduce_columns_with_m
              @force_reduce_row:
              cmp eax,esi
              jz @abnormal_exit
              @reduce_row_elements:
              cmp [ebx],esi
              ja @after_row_reduction
              sub [ebx],eax
              @after_row_reduction:
              add ebx,04h
              dec ch
              jnz @reduce_row_elements
              dec edx
              jnz @row_minimum

              @reduce_columns_with_minimum
              mov esi,[mtx]
              mov ebx,ebp
              lea edi,[ebp*04h]
              @column_minimum:
              mov ecx,ebp
              mov eax,00FFFFFFh
              mov edx,esi
              mov ch,cl
              @find_column_minimum:
              cmp [esi],eax
              ja @after_column_test
              mov eax,[esi]
              test eax,eax
              jz @next_decrease_column
              @after_column_test:
              add esi,edi
              dec cl
              jnz @find_column_minimum
              @start_reduce_column:
              cmp eax,00FFFFFFh
              jz @abnormal_exit
              mov esi,edx
              @reduce_column_elements:
              cmp dword ptr [esi],00FFFF
              ja @after_column_reduction
              sub [esi],eax
              @after_column_reduction:
              add esi,edi
              dec ch
              jnz @reduce_column_element
              @next_decrease_column:
              lea esi,[edx+04h]
              dec ebx
              jnz @column_minimum

              @determine_start0_system:
              mov [sys0],ebx
              mov edi,[marks]
              mov ebx,ebp
              mov eax,0102h
              mov esi,[mtx]
              xor ecx,ecx
              dec ebx
              push esi
              xor edx,edx
              @start_0system:
              lea esi,[esi+ebx*04h]
              @find_free0:
              test [edi+edx],al
              jnz @check_next_item
              cmp [esi],ecx
              jnz @check_next_item
              or [edi+edx],al
              or [edi+ebx],ah
              or [esi+03h],ah
              inc [sys0]
              jmp @next_column
              @check_next_item:
              inc edx
              lea esi,[esi+ebp*04h]
              cmp edx,ebp
              jnz @find_free0
              @next_column:
              mov esi,[esp]
              xor edx,edx
              dec ebx
              jns @start_0system
              pop ebx

              cmp ebp,[sys0]
              jz @count_result
              mov ecx,[mtxdblsize]
              mov eax,01010101h
              @clear_line_marks:
              and [edi],eax
              add edi,04h
              dec ecx
              jnz @clear_line_marks
              pushad
              jmp @@2nd_step
              @@1st_step:
              mov edi,[marks]
              cmp ebp,[sys0]
              jz @count_result_with_POPA
              mov ebx,ebp
              add edi,ebp
              mov al,0FDh
              lea edx,[edx+ebx*04h-01h]
              dec edi
              @remove_line_marks_set_cols:
              mov esi,edx
              mov [edi],bh
              mov ecx,ebp
              @check_star_mark:
              and [esi],al
              jz @marks_tested
              mov ah,[esi]
              and ah,01h
              or [edi],ah
              @marks_tested:
              lea esi,[esi+ebp*04h]
              dec ecx
              jnz @check_star_mark
              @star_next_column:
              sub edx,04h
              dec edi
              dec ebx
              jnz @remove_line_marks_set
              @@2nd_step:
              mov esi,[mtx]
              mov ecx,ebp
              mov ebx,[marks]
              mov edx,00FFFFFFh
              @search_free0:
              mov edi,[marks]
              xor eax,eax
              mov ch,byte ptr [mtxsize]
              @search_free0_prev_marked:
              test byte ptr [ebx],02h
              jz @look_for_zero
              inc ebx
              dec cl
              jz @@5th_step
              lea esi,[esi+ebp*04h]
              jmp @search_free0_prev_mar
              @look_for_zero:
              test byte ptr [edi],01h
              jnz @handle_column_counter
              cmp edx,[esi]
              jle @handle_column_counter
              mov edx,[esi]
              test edx,edx
              jz @decide_next_step
              add esp,20h
              pushad
              jmp @step_next_item
              @handle_column_counter:
              test byte ptr [esi+03h],01
              jz @step_next_item
              mov eax,edi
              @step_next_item:
              add esi,04h
              inc edi
              dec ch
              jnz @look_for_zero
              inc ebx
              dec cl
              jnz @search_free0
              jmp @@5th_step
              @decide_next_step:
              mov edx,0102h
              or [ebx],dl
              test eax,eax
              jz @continue_search
              @@3rd_step:
              and byte ptr [eax],0FEh
              mov [esi+03h],dl
              jmp @@2nd_step
              @continue_search:
              mov ebx,ecx
              lea eax,[esi+03h]
              dec ch
              jz @@4th_step
              add esi,07h
              inc edi
              @search_0star:
              test [esi],dh
              jz @next_0star_test
              and byte ptr [edi],0FEh
              or [eax],dl
              jmp @@2nd_step
              @next_0star_test:
              add esi,04h
              inc edi
              dec ch
              jnz @search_0star
              @@4th_step:
              or [eax],dh
              xor ecx,ecx
              xor edx,edx
              inc [sys0]
              mov cl,bl
              mov edi,ebp
              mov dl,bh
              sub edi,ecx
              mov ecx,ebp
              mov eax,[mtx]
              lea ebx,[ebp*04h]
              sub ecx,edx
              mov dl,01h
              push eax
              @check_column:
              shl ecx,02h
              lea esi,[eax+ecx+03h]
              xor eax,eax
              @search_star_in_column:
              test [esi],dl
              jz @prepare_for_next_item
              cmp eax,edi
              jnz @found_0_star
              @prepare_for_next_item:
              inc eax
              add esi,ebx
              cmp ebp,eax
              jnz @search_star_in_column
              pop edx
              jmp @@1st_step
              @found_0_star:
              mov byte ptr [esi],00h
              sub esi,ecx
              mov edi,eax
              xor ecx,ecx
              mov eax,0102h
              @search_colon_in_row:
              test [esi],al
              jnz @found_0_colon
              inc ecx
              add esi,04h
              cmp ecx,ebp
              jnz @search_colon_in_row
              @found_0_colon:
              mov [esi],ah
              mov eax,[esp]
              mov dl,01h
              jmp @check_column
              @@5th_step:
              mov esi,[mtx]
              sub ebx,ebp
              mov ecx,ebp
              mov al,01h
              mov ebp,ebx
              add esi,03h
              @decrease_next_row:
              mov ch,[esp+08h]
              mov edi,ebp
              test byte ptr [ebx],02h
              jz @start_decrease_current
              mov ah,0FCh
              @increase_double_markeds:
              test [edi],al
              jz @step_next_element
              test [esi],ah
              jnz @step_next_element
              add [esi-03h],edx
              @step_next_element:
              add esi,04h
              inc edi
              dec ch
              jnz @increase_double_marke
              inc ebx
              dec cl
              jnz @decrease_next_row
              popad
              pushad
              jmp @decide_next_step
              @start_decrease_current_row:
              mov ah,0FFh
              @decrease_current_row:
              test [edi],al
              jnz @jump_next_element
              test [esi],ah
              jnz @jump_next_element
              sub [esi-03h],edx
              @jump_next_element:
              add esi,04h
              inc edi
              dec ch
              jnz @decrease_current_row
              @step_on_next_row:
              inc ebx
              dec cl
              jnz @decrease_next_row
              popad
              pushad
              jmp @decide_next_step
              @count_result_with_POPAD:
              add esp,20h
              @count_result:
              mov esi,[save]
              shl ebp,02h
              mov ebx,edi
              xor ecx,ecx
              mov edi,[mtx]
              mov eax,01000000h
              push edi
              mov edx,[sys0]
              @count_optimum:
              @test_elements:
              scasd
              jnz @test_elements
              @increase_optimum:
              sub edi,04h
              sub edi,[esp]
              add [esp],ebp
              add ecx,[esi+edi]
              add esi,ebp
              shr edi,02h
              mov [ebx],edi
              inc ebx
              dec edx
              mov edi,[esp]
              jnz @count_optimum
              @store_optimum:
              pop eax
              shr ebp,02h
              mov eax,ecx

              [ Szerkesztve ]

              (#27) P.H.


                P.H.
                (senior tag)

                Algoritmusban felhasználásra kihegyezve (több 100000 lefutás); Shanghai-on 1.4 IPC, ezredmásodpercenként legalább 20 db 25x25-ös mátrix megoldása.

                pushad
                mov ebx,offset(MARKS)
                lea ecx,[ebp+ebp]
                xor edx,edx
                lea edi,[ebx+ebp]
                neg ebp
                @mark0:
                sub ecx,04h
                mov [ebx],edx
                lea ebx,[ebx+04h]
                jg @mark0
                @@REDUCE_ROWS:
                mov [esp+__SYS0],ebp
                mov ebx,ebp
                @rowmin:
                mov esi,01000000h
                xor edx,edx
                mov ecx,ebp
                @findrowmin:
                cmp esi,[eax]
                cmovz edx,ecx
                cmova esi,[eax]
                add ecx,01h
                lea eax,[eax+04h]
                jnz @findrowmin
                sub ecx,ebp
                cmp esi,01000000h
                jz @specific
                lea eax,[eax+ebp*04h]
                @subrow:
                xor edx,edx
                cmp byte ptr [eax+03h],00h
                cmovz edx,esi
                sub [eax],edx
                sub ecx,01h
                lea eax,[eax+04h]
                jnz @subrow
                jmp @reducenxrow
                @specific:
                test edx,edx
                jz @@ABNORMAL_EXIT
                test byte ptr [edi+edx],01h
                jz @mark
                @@ABNORMAL_EXIT:
                add esp,20h
                xor eax,eax
                mov edx,7FFFFFFFh
                stc
                ret
                @mark:
                or byte ptr [edi+ebx],10h
                add ecx,ebx
                or byte ptr [edi+edx],01h
                add dword ptr [esp+__SYS0],01h
                mov [edi+ecx],dl
                @reducenxrow:
                add ebx,01h
                jnz @rowmin
                @@REDUCE_COLUMNS:
                mov ebx,ebp
                mov esi,[esp+__MTX]
                @colmin:
                mov ecx,ebp
                xor eax,eax
                mov edx,01000000h
                neg ebp
                @findcolmin:
                cmp edx,[esi]
                cmovz eax,ecx
                cmova edx,[esi]
                add ecx,01h
                lea esi,[esi+ebp*04h]
                jnz @findcolmin
                neg ebp
                cmp edx,01000000h
                mov ecx,ebp
                jb @subcol
                test eax,eax
                jz @@ABNORMAL_EXIT
                @subcol:
                lea esi,[esi+ebp*04h]
                xor eax,eax
                cmp byte ptr [esi+03h],00h
                cmovz eax,edx
                sub [esi],eax
                add ecx,01h
                jnz @subcol
                add ebx,01h
                lea esi,[esi+04h]
                jnz @colmin
                mov eax,00000001h
                neg ebp
                @@START0_SYSTEM:
                xor ecx,ecx
                sub esi,04h
                sub ebx,eax
                sub ecx,ebp
                mov edx,esi
                @findfree0:
                cmp [esi],eax
                jb @markitem
                @nxrow:
                add ecx,eax
                lea esi,[esi+ebp*04h]
                jnz @findfree0
                jmp @nxcol
                @markitem:
                bts dword ptr [edi+ecx],04h
                jc @nxrow
                add ecx,ebp
                mov [esi+03h],al
                add [esp+__SYS0],eax
                mov [edi+ecx],bl
                or [edi+ebx],al
                @nxcol:
                lea ecx,[ebx+ebp]
                mov esi,edx
                test ecx,ecx
                jnz @@START0_SYSTEM
                cmp [esp+__SYS0],ecx
                jz @count_result_MTX
                sub esp,_SAVE
                jmp @@2ND_STEP
                @@3RD_STEP:
                mov byte ptr [esi+03h],02h
                and byte ptr [edi+edx],11111110b
                @@2ND_STEP:
                xor ebx,ebx
                mov esi,[esp+_SAVE+__MTX]
                xor ecx,ecx
                mov edx,00FFFFFFh
                sub ebx,ebp
                @free0:
                sub ecx,ebp
                @freerow:
                test byte ptr [edi+ebx],02h
                jz @zeroinrow
                add ebx,01h
                lea esi,[esi+ebp*04h]
                jnz @freerow
                jmp @@5TH_STEP
                @zeroinrow:
                xor eax,eax
                test byte ptr [edi+ecx],01h
                jnz @nx2col
                add eax,[esi]
                jz @@DECIDE_NEXT_STEP
                cmp edx,eax
                cmova edx,eax
                jbe @nx2col
                add esp,_SAVE
                pushad
                @nx2col:
                add ecx,01h
                lea esi,[esi+04h]
                jnz @zeroinrow
                add ebx,01h
                jnz @free0
                @@5TH_STEP:
                xor ecx,ecx
                mov esi,[esp+_SAVE+__MTX]
                sub ebx,ebp
                @nx5row:
                sub ecx,ebp
                test byte ptr [edi+ebx],02h
                jz @decrease_row_free
                @increase_double_markeds:
                mov al,[esi+03h]
                and al,11111100b
                bt dword ptr [edi+ecx],00h
                sbb al,00h
                sbb eax,eax
                and eax,edx
                add [esi],eax
                add ecx,01h
                lea esi,[esi+04h]
                jnz @increase_double_markeds
                jmp @step5row
                @decrease_row_free:
                bt dword ptr [edi+ecx],00h
                mov al,[esi+03h]
                adc al,00h
                mov eax,00000000h
                cmovz eax,edx
                sub [esi],eax
                add ecx,01h
                lea esi,[esi+04h]
                jnz @decrease_row_free
                @step5row:
                add ebx,01h
                jnz @nx5row
                popad
                sub esp,20h
                @@DECIDE_NEXT_STEP:
                mov edx,0FFFFFF00h
                lea eax,[ebx+ebp]
                or byte ptr [edi+ebx],02h
                add dl,[edi+eax]
                jnz @@3RD_STEP
                @@4TH_STEP:
                mov edx,[esp+_SAVE+__MTX]
                @colon_to_star:
                mov [edi+eax],cl
                add ecx,ebp
                mov byte ptr [esi+03h],01h
                xor eax,eax
                lea esi,[edx+ecx*04h]
                shl ecx,02h
                and byte ptr [edi+ebx],11111101b
                sub eax,ebp
                @search_star_in_column:
                test byte ptr [esi+03h],01h
                jz @nxstar
                cmp eax,ebx
                jnz @0_star
                @nxstar:
                add eax,01h
                lea esi,[esi+ebp*04h]
                jnz @search_star_in_column
                jmp @@1ST_STEP
                @0_star:
                mov ebx,eax
                mov byte ptr [esi+03h],00h
                add eax,ebp
                sub esi,ecx
                xor ecx,ecx
                mov byte ptr [edi+eax],00h
                sub ecx,ebp
                @search_colon_in_row:
                test byte ptr [esi+03h],02h
                jnz @colon_to_star
                add ecx,01h
                lea esi,[esi+04h]
                jnz @search_colon_in_row
                @error:
                nop
                @@1ST_STEP:
                xor ebx,ebx
                xor eax,eax
                add dword ptr [esp+_SAVE+__SYS0],01h
                jz @count_result_STACK
                sub ebx,ebp
                mov cl,[edi+00h]
                jmp @nxclear
                @clear_colon:
                and byte ptr [esi+03h],11111101b
                add eax,01h
                lea esi,[esi+04h]
                jnz @clear_colon
                @nxclear:
                sub eax,ebp
                @markedrow:
                test byte ptr [edi+ebx],02h
                mov esi,edx
                mov byte ptr [edi+ebx],00h
                jnz @clear_colon
                add ebx,01h
                lea edx,[edx+ebp*04h]
                jnz @markedrow
                @markcol:
                movsx edx,byte ptr [edi+ebx]
                add ebx,01h
                add eax,01h
                mov byte ptr [edi+edx],01h
                jnz @markcol
                mov [edi+00h],cl
                jmp @@2ND_STEP
                @count_result_STACK:
                add esp,_SAVE
                @count_result_MTX:
                xor ecx,ecx
                xor eax,eax
                mov esi,[esp+__SAVE]
                mov ebx,[esp+__MARKS]
                add esp,20h
                @results:
                movsx edx,byte ptr [edi+ecx]
                add ecx,01h
                add edx,ebp
                add eax,[esi+edx*04h]
                cmp ecx,ebp
                mov [ebx],dl
                lea esi,[esi+ebp*04h]
                lea ebx,[ebx+01h]
                jnz @results

                [ Szerkesztve ]

                (#28) P.H.


                  P.H.
                  (senior tag)

                  Utolsó felvonás, két bevezető ciklus összevonása után.

                  Néhány IPC-mérés a lépések ciklusaira (végtelen ciklusban mérve):
                  @@REDUCE_ROWS:1.8 IPC
                  @@REDUCE_COLUMNS:1.6 IPC
                  @@2ND_STEP: 0.9 IPC (ez a leggyakrabban lefutó ciklus)
                  @@5TH_STEP: 2.2 IPC
                  @@1ST_STEP: 1.5 IPC

                  Úgy tűnik, az AMD-n (a Bulldozer-ig bezárólag) a legjobb stratégia az, ha a ciklusokban az utasítások fele [ ] referenciát tartalmaz, azaz a memóriahivatkozások mellett bizonyos ADD reg,imm és MOV reg,reg utasítások helyett azok LEA reg,[reg+imm] vagy LEA reg,[reg] megfelelőiket használom, ezek méretre ugyanakkorák, viszont a 3 AGU valamelyikében futnak az ALU-k helyett.

                  pushad
                  mov ebx,offset(MARKS)
                  lea edx,[ebp+ebp]
                  xor ecx,ecx
                  lea edi,[ebx+ebp]
                  neg ebp
                  @mark0:
                  sub edx,04h
                  mov [ebx],ecx
                  lea ebx,[ebx+04h]
                  jg @mark0
                  @@REDUCE_ROWS:
                  mov [esp+__SYS0],ebp
                  mov ebx,ebp
                  sub esp,_SAVE
                  @rowmin:
                  mov ecx,ebp
                  mov esi,01000000h
                  xor edx,edx
                  @findrowmin:
                  cmp esi,[eax]
                  cmovz edx,ecx
                  cmova esi,[eax]
                  add ecx,01h
                  lea eax,[eax+04h]
                  jnz @findrowmin
                  sub ecx,ebp
                  cmp esi,01000000h
                  jz @specific
                  lea eax,[eax+ebp*04h]
                  @subrow:
                  xor edx,edx
                  cmp byte ptr [eax+03h],00h
                  cmovz edx,esi
                  sub [eax],edx
                  sub ecx,01h
                  lea eax,[eax+04h]
                  jnz @subrow
                  jmp @reducenxrow
                  @specific:
                  test edx,edx
                  jz @@ABNORMAL_EXIT
                  test byte ptr [edi+edx],01h
                  jz @mark
                  @@ABNORMAL_EXIT:
                  add esp,40h
                  xor eax,eax
                  mov edx,7FFFFFFFh
                  stc
                  ret
                  @mark:
                  or byte ptr [edi+ebx],10h
                  add ecx,ebx
                  or byte ptr [edi+edx],01h
                  add dword ptr [esp+_SAVE+__SYS0],01h
                  mov [edi+ecx],dl
                  jz @count_result_STACK
                  @reducenxrow:
                  add ebx,01h
                  jnz @rowmin
                  @@RECUDE_COLUMNS:
                  neg ebp
                  @nxcolmin:
                  mov edx,ebp
                  sub ebx,01h
                  sub eax,04h
                  add edx,ebx
                  js @@2ND_STEP
                  test byte ptr [edi+ebx],01h
                  jnz @nxcolmin
                  neg ebp
                  mov edx,01000000h
                  mov ecx,ebp
                  @findcolmin:
                  cmp edx,[eax]
                  cmova edx,[eax]
                  add ecx,01h
                  lea eax,[eax+ebp*04h]
                  jnz @findcolmin
                  lea ecx,[ebp-01h]
                  neg ebp
                  cmp edx,01000000h
                  jz @@ABNORMAL_EXIT
                  @subcol:
                  xor esi,esi
                  add ecx,01h
                  jz @nxcolmin
                  lea eax,[eax+ebp*04h]
                  cmp byte ptr [eax+03h],00h
                  cmovz esi,edx
                  sub [eax],esi
                  jnz @subcol
                  bts dword ptr [edi+ecx],04h
                  jc @subcol
                  bts dword ptr [edi+ebx],00h
                  lea esi,[ecx+ebp]
                  jc @subcol
                  add dword ptr [esp+_SAVE+__SYS0],01h
                  mov byte ptr [eax+03h],01h
                  mov [edi+esi],bl
                  jnz @subcol
                  jmp @count_result_STACK
                  @@3RD_STEP:
                  or byte ptr [edi+ebx],02h
                  mov byte ptr [esi+03h],02h
                  and byte ptr [edi+edx],11111110b
                  @@2ND_STEP:
                  xor ebx,ebx
                  mov esi,[esp+_SAVE+__MTX]
                  xor ecx,ecx
                  mov edx,00FFFFFFh
                  sub ebx,ebp
                  @free0:
                  sub ecx,ebp
                  @freerow:
                  test byte ptr [edi+ebx],02h
                  jz @zeroinrow
                  add ebx,01h
                  lea esi,[esi+ebp*04h]
                  jnz @freerow
                  jmp @@5TH_STEP
                  @zeroinrow:
                  xor eax,eax
                  test byte ptr [edi+ecx],01h
                  jnz @nx2col
                  add eax,[esi]
                  jz @@DECIDE_NEXT_STEP
                  cmp edx,eax
                  jbe @nx2col
                  add esp,_SAVE
                  lea edx,[eax] //mov edx,eax
                  pushad
                  @nx2col:
                  add ecx,01h
                  lea esi,[esi+04h]
                  jnz @zeroinrow
                  add ebx,01h
                  jnz @free0
                  @@5TH_STEP:
                  xor ecx,ecx
                  mov esi,[esp+_SAVE+__MTX]
                  sub ebx,ebp
                  @nx5row:
                  sub ecx,ebp
                  test byte ptr [edi+ebx],02h
                  jnz @increase_double_markeds
                  @decrease_row_free:
                  bt dword ptr [edi+ecx],00h
                  mov al,[esi+03h]
                  adc al,00h
                  mov eax,00000000h
                  cmovz eax,edx
                  sub [esi],eax
                  add ecx,01h
                  lea esi,[esi+04h]
                  jnz @decrease_row_free
                  jmp @step5row
                  @increase_double_markeds:
                  mov al,[esi+03h]
                  and al,11111100b
                  bt dword ptr [edi+ecx],00h
                  sbb al,00h
                  mov eax,00000000h
                  cmovc eax,edx
                  add [esi],eax
                  add ecx,01h
                  lea esi,[esi+04h]
                  jnz @increase_double_markeds
                  @step5row:
                  add ebx,01h
                  jnz @nx5row
                  jmp @@5TH_STEP
                  popad
                  sub esp,20h
                  @@DECIDE_NEXT_STEP:
                  mov edx,0FFFFFF00h
                  lea eax,[ebx+ebp]
                  add dl,[edi+eax]
                  jnz @@3RD_STEP
                  @@4TH_STEP:
                  mov edx,[esp+_SAVE+__MTX]
                  @colon_to_star:
                  mov [edi+eax],cl
                  add ecx,ebp
                  mov byte ptr [esi+03h],01h
                  xor eax,eax
                  lea esi,[edx+ecx*04h]
                  shl ecx,02h
                  and byte ptr [edi+ebx],11111101b
                  sub eax,ebp
                  @search_star_in_column:
                  test byte ptr [esi+03h],01h
                  jz @nxstar
                  cmp eax,ebx
                  jnz @0_star
                  @nxstar:
                  add eax,01h
                  lea esi,[esi+ebp*04h]
                  jnz @search_star_in_column
                  jmp @@1ST_STEP
                  @0_star:
                  mov ebx,eax
                  mov byte ptr [esi+03h],00h
                  add eax,ebp
                  sub esi,ecx
                  xor ecx,ecx
                  mov byte ptr [edi+eax],00h
                  sub ecx,ebp
                  @search_colon_in_row:
                  test byte ptr [esi+03h],02h
                  jnz @colon_to_star
                  add ecx,01h
                  lea esi,[esi+04h]
                  jnz @search_colon_in_row
                  @error:
                  nop
                  @@1ST_STEP:
                  xor ebx,ebx
                  xor eax,eax
                  add dword ptr [esp+_SAVE+__SYS0],01h
                  jz @count_result_STACK
                  sub ebx,ebp
                  mov cl,[edi+00h]
                  jmp @nxclear
                  @clear_colon:
                  and byte ptr [esi+03h],11111101b
                  add eax,01h
                  lea esi,[esi+04h]
                  jnz @clear_colon
                  @nxclear:
                  sub eax,ebp
                  @markedrow:
                  test byte ptr [edi+ebx],02h
                  mov esi,edx
                  mov byte ptr [edi+ebx],00h
                  jnz @clear_colon
                  add ebx,01h
                  lea edx,[edx+ebp*04h]
                  jnz @markedrow
                  @markcol:
                  movsx edx,byte ptr [edi+ebx]
                  add eax,01h
                  lea ebx,[ebx+01h]
                  mov byte ptr [edi+edx],01h
                  jnz @markcol
                  mov [edi+00h],cl
                  jmp @@2ND_STEP
                  @count_result_STACK:
                  { EDI -> MARKS memory end
                  EBP: row/column quantity
                  add esp,_SAVE
                  xor ecx,ecx
                  xor eax,eax
                  mov esi,[esp+__SAVE]
                  mov ebx,[esp+__MARKS]
                  add esp,20h
                  @results:
                  movsx edx,byte ptr [edi+ecx]
                  lea ecx,[ecx+01h]
                  add edx,ebp
                  add eax,[esi+edx*04h]
                  cmp ecx,ebp
                  mov [ebx],dl
                  lea esi,[esi+ebp*04h]
                  lea ebx,[ebx+01h]
                  jnz @results

                  [ Szerkesztve ]


                  P.H.
                  (senior tag)

                  @@2ND_STEP lecserélve, "kiegyenesítve", így már 0.9 IPC helyett hozza a 2.0 IPC-t, kevesebb utasítással.
                  A teljes, előzőekben említett algoritmus IPC-je így már (mivel a 2. step lefutása a leggyakoribb) 1.9 körüli.

                  Carry Flag a programozó legjobb barátja ... legalábbis AMD-n

                  @@2ND_STEP:
                  xor ecx,ecx
                  xor ebx,ebx
                  mov esi,[esp+_SAVE+__MTX]
                  mov edx,00FFFFFFh
                  sub ebx,ebp
                  @free0:
                  sub ecx,ebp
                  @zeroinrow:
                  bt dword ptr [edi+ebx],01h
                  setc al
                  bt dword ptr [edi+ecx],00h
                  adc al,00h
                  cmp edx,[esi]
                  adc al,00h
                  jnz @nx2col
                  xor edx,edx
                  add esp,_SAVE
                  add edx,[esi]
                  pushad
                  jz @@DECIDE_NEXT_STEP
                  @nx2col:
                  add ecx,01h
                  lea esi,[esi+04h]
                  jnz @zeroinrow
                  add ebx,01h
                  jnz @free0

                  [ Szerkesztve ]


                  P.H.
                  (senior tag)

                  Lemérve.

                  Előző:
                  "Algoritmusban felhasználásra kihegyezve (több 100000 lefutás); Shanghai-on 1.4 IPC, ezredmásodpercenként legalább 20 db 25x25-ös mátrix megoldása."

                  Az újjal:
                  "Algoritmusban felhasználásra kihegyezve (több 100000 lefutás); Shanghai-on 1.9 IPC, ezredmásodpercenként legalább 28 db 25x25-ös mátrix megoldása."

                  (#31) P.H.


                    P.H.
                    (senior tag)

                    @@2ND_STEP újra módosítva, mostmár az Intel CPU-kon is hozza a 2.0 IPC-t, így a teljes algoritmus is (Intel esetében az ADC és SBB legalább Pentium Pro óta, a CMOVcc legalább Core2 óta 2 micro-op, egészen Nehalem-ig :(( , AMD-nél K7 óta 1 micro-op, 1 órajel lefutási idővel; pedig ezek az ugrásmentesítés és az ILP-kihasználás alapkövei a SETcc mellett).

                    Mivel az utasításszám is csökkent és a belső ciklustörzsből is kiemelhető pár utasítás, így AMD-n is gyorsabb az előzőnél egy kicsivel.

                    Az első adandó alkalommal lemér(et)em Bobcat-on is. Ha ott is tudja hozni a 2 körüli IPC-t, akkor mivel nagyon hasonlóak felépítésben - a Bulldozer az emelt órajeleivel valóban speed racer lesz integer-ben - ha marad a legtöbb integer utasítás 1 órajeles lefutási értéke.

                    @@2ND_STEP:
                    xor ebx,ebx
                    xor ecx,ecx
                    mov esi,[esp+_SAVE+__MTX]
                    sub ebx,ebp
                    mov edx,00FFFFFFh
                    @free0:
                    bt dword ptr [edi+ebx],01h
                    setc ah
                    sub ecx,ebp
                    @zeroinrow:
                    mov al,[edi+ecx]
                    and al,01h
                    cmp edx,[esi]
                    adc al,ah
                    jnz @nx2col
                    xor edx,edx
                    add esp,20h
                    add edx,[esi]
                    pushad
                    jz @@DECIDE_NEXT_STEP
                    @nx2col:
                    add ecx,01h
                    lea esi,[esi+04h]
                    jnz @zeroinrow
                    add ebx,01h
                    jnz @free0

                    [ Szerkesztve ]

                    (#32) P.H.


                      P.H.
                      (senior tag)

                      Kód, még jobban kiegyenesítve, mostmár a teljes mártix egy ciklus, egy-egy sora helyett. AMD-n 2.3 IPC.

                      @@2ND_STEP:
                      neg ebp
                      mov esi,[esp+__MTX]
                      sub esp,20h
                      mov ebx,ebp
                      mov edx,00FFFFFFh
                      mov ecx,ebp
                      @zeroinrow:
                      bt dword ptr [edi+ebx],01h
                      setc ah
                      mov al,[edi+ecx]
                      and al,01h
                      cmp edx,[esi]
                      adc al,ah
                      jnz @nx2col
                      xor edx,edx
                      add esp,20h
                      add edx,[esi]
                      jz @@DECIDE_NEXT_STEP
                      pushad
                      @nx2col:
                      add cl,01h
                      lea esi,[esi+04h]
                      cmovz ecx,ebp
                      adc ebx,00h
                      jnz @zeroinrow

                      Most szembesültem először azzal igazán, hogy az AMD féle generális "single cycle execution" + a 2 loads/cycle felépítésre megírt program Intel-en (Core2) fájóan lassabb, mint AMD-n. No ekkor mit lehet csinálni? Az általános gyors vagy AMD-specializált (de az általánosan elterjedt CPU-kon lassabb) megoldás a jobb?

                      [ Szerkesztve ]

                      (#33) P.H.


                        P.H.
                        (senior tag)

                        Kissé átszerkesztve a teljes algoritmust (teljesen 32 bites adatokon dolgozik) az utasításszám csökkent.
                        Generálisan AMD-re és Intel-re:

                        pushad
                        mov ebx,offset(MARKS)
                        lea edx,[ebp+ebp]
                        xor ecx,ecx
                        lea edi,[ebx+ebp*04h]
                        imul ebp,BYTE(-4)
                        @mark0:
                        sub edx,01h
                        mov [ebx],ecx
                        lea ebx,[ebx+04h]
                        jg @mark0
                        @@REDUCE_ROWS:
                        mov [esp+__SYS0],ebp
                        mov ebx,ebp
                        @rowmin:
                        mov ecx,ebp
                        mov esi,01000000h
                        xor edx,edx
                        @findrowmin:
                        cmp esi,[eax]
                        cmovz edx,ecx
                        cmova esi,[eax]
                        add ecx,04h
                        lea eax,[eax+04h]
                        jnz @findrowmin
                        sub ecx,ebp
                        cmp esi,01000000h
                        jz @specific
                        add eax,ebp
                        @subrow:
                        xor edx,edx
                        cmp byte ptr [eax+03h],00h
                        cmovz edx,esi
                        sub [eax],edx
                        sub ecx,04h
                        lea eax,[eax+04h]
                        jnz @subrow
                        jmp @reducenxrow
                        @specific:
                        test edx,edx
                        jz @@ABNORMAL_EXIT
                        test byte ptr [edi+edx],01h
                        jz @mark
                        @@ABNORMAL_EXIT:
                        add esp,20h
                        stc
                        ret
                        @mark:
                        or byte ptr [edi+ebx],10h
                        add ecx,ebx
                        or byte ptr [edi+edx],01h
                        add dword ptr [esp+__SYS0],04h
                        mov [edi+ecx],edx
                        jz @count_result_STACK
                        @reducenxrow:
                        add ebx,04h
                        jnz @rowmin
                        @@RECUDE_COLUMNS:
                        sub ebx,04h
                        sub eax,04h
                        cmp ebx,ebp
                        jl @@2ND_STEP
                        test byte ptr [edi+ebx],01h
                        jnz @@RECUDE_COLUMNS
                        mov edx,01000000h
                        mov ecx,ebp
                        @findcolmin:
                        cmp edx,[eax]
                        cmova edx,[eax]
                        add eax,ebp
                        add ecx,04h
                        jnz @findcolmin
                        cmp edx,01000000h
                        lea ecx,[ebp-04h]
                        jz @@ABNORMAL_EXIT
                        @subcol:
                        xor esi,esi
                        add ecx,04h
                        jz @@RECUDE_COLUMNS
                        sub eax,ebp
                        cmp byte ptr [eax+03h],00h
                        cmovz esi,edx
                        sub [eax],esi
                        jnz @subcol
                        bts dword ptr [edi+ecx],04h
                        jc @subcol
                        bts dword ptr [edi+ebx],00h
                        mov esi,ecx
                        jc @subcol
                        sub esi,ebp
                        add dword ptr [esp+__SYS0],04h
                        mov byte ptr [eax+03h],01h
                        mov [edi+esi],ebx
                        jnz @subcol
                        jmp @count_result_STACK
                        @@3RD_STEP:
                        or byte ptr [edi+ebx],02h
                        mov byte ptr [esi+03h],02h
                        and byte ptr [edi+edx],11111110b
                        @@2ND_STEP:
                        mov esi,[esp+__MTX]
                        sub esp,20h
                        mov ebx,ebp
                        mov edx,00FFFFFFh
                        @nx2row:
                        bt dword ptr [edi+ebx],01h
                        mov ecx,ebp
                        setc ah
                        @zeroinrow:
                        mov al,[edi+ecx]
                        and al,01h
                        cmp edx,[esi]
                        adc al,ah
                        jnz @nx2col
                        xor edx,edx
                        add esp,20h
                        add edx,[esi]
                        jz @@DECIDE_NEXT_STEP
                        pushad
                        @nx2col:
                        add ecx,04h
                        lea esi,[esi+04h]
                        jnz @zeroinrow
                        add ebx,04h
                        jnz @nx2row
                        @@5TH_STEP:
                        mov esi,[esp+_SAVE+__MTX]
                        mov ebx,ebp
                        @nx5row:
                        test byte ptr [edi+ebx],02h
                        mov ecx,ebp
                        jnz @increase_double_markeds
                        @decrease_row_free:
                        bt dword ptr [edi+ecx],00h
                        mov al,[esi+03h]
                        adc al,00h
                        mov eax,00000000h
                        cmovz eax,edx
                        sub [esi],eax
                        add ecx,04h
                        lea esi,[esi+04h]
                        jnz @decrease_row_free
                        jmp @step5row
                        @increase_double_markeds:
                        mov al,[esi+03h]
                        and al,11111100b
                        bt dword ptr [edi+ecx],00h
                        sbb al,00h
                        mov eax,00000000h
                        cmovc eax,edx
                        add [esi],eax
                        add ecx,04h
                        lea esi,[esi+04h]
                        jnz @increase_double_markeds
                        @step5row:
                        add ebx,04h
                        jnz @nx5row
                        popad
                        xor edx,edx
                        @@DECIDE_NEXT_STEP:
                        mov eax,ebx
                        sub eax,ebp
                        add edx,[edi+eax]
                        jnz @@3RD_STEP
                        @@4TH_STEP:
                        mov edx,[esp+__MTX]
                        @colon_to_star:
                        mov [edi+eax],ecx
                        sub ecx,ebp
                        mov byte ptr [esi+03h],01h
                        lea esi,[edx+ecx]
                        mov eax,ebp
                        and byte ptr [edi+ebx],11111101b
                        @search_star_in_column:
                        test byte ptr [esi+03h],01h
                        jz @nxstar
                        cmp eax,ebx
                        jnz @0_star
                        @nxstar:
                        sub esi,ebp
                        add eax,04h
                        jnz @search_star_in_column
                        jmp @@1ST_STEP
                        @0_star:
                        mov ebx,eax
                        mov byte ptr [esi+03h],00h
                        sub eax,ebp
                        sub esi,ecx
                        mov dword ptr [edi+eax],00000000h
                        mov ecx,ebp
                        @search_colon_in_row:
                        test byte ptr [esi+03h],02h
                        jnz @colon_to_star
                        add ecx,04h
                        lea esi,[esi+04h]
                        jmp @search_colon_in_row
                        @@1ST_STEP:
                        add dword ptr [esp+__SYS0],04h
                        jz @count_result_STACK
                        mov ebx,ebp
                        mov ecx,[edi+00h]
                        jmp @nxclear
                        @clear_colon:
                        and byte ptr [esi+03h],11111101b
                        add eax,04h
                        lea esi,[esi+04h]
                        jnz @clear_colon
                        @nxclear:
                        mov eax,ebp
                        @markedrow:
                        test byte ptr [edi+ebx],02h
                        mov esi,edx
                        mov byte ptr [edi+ebx],00h
                        jnz @clear_colon
                        sub edx,ebp
                        add ebx,04h
                        jnz @markedrow
                        @markcol:
                        mov edx,[edi+ebx]
                        add eax,04h
                        lea ebx,[ebx+04h]
                        mov byte ptr [edi+edx],01h
                        jnz @markcol
                        mov [edi+00h],ecx
                        jmp @@2ND_STEP
                        @count_result_STACK:
                        xor ecx,ecx
                        neg ebp
                        xor eax,eax
                        mov esi,[esp+__SAVE]
                        mov ebx,[esp+__MARKS]
                        add esp,20h
                        @results:
                        mov edx,[edi+ecx]
                        add ecx,04h
                        add edx,ebp
                        add eax,[esi+edx]
                        shr edx,02h
                        add esi,ebp
                        cmp ecx,ebp
                        mov [ebx],dl
                        lea ebx,[ebx+01h]
                        jnz @results

                        [ Szerkesztve ]

                        (#34) P.H.


                          P.H.
                          (senior tag)

                          Nem hagy(ott) nyugodni a kisördög. A teljesen 32 bitesre átírással megnyílt pár lehetőség: külön jelölő byte az oszlopnak, külön a sornak, külön a bevezető sorjelölésnek, így sikerült drasztikusan csökkenteni a load-op-store utasításokat, sima store-ral helyettesítve őket.

                          Kombinálva ezt az AMD 2 load/cycle felépítésével, sikerült elérni a 30 db 25x25-ös mátrix per ezredmásodperc teljesítményt, 2.6 GHz-es Shanghai-on.

                          Csak Intel-en ne lenne fele ilyen gyors így, 2.5 GHz Core2-n tesztelve... (Sandy Bridge-ig, ami ugyancsak 2 load/cycle felépítésű - lesz -).

                          Az algoritmuson látható, hogy egyetlen szorzáson kívül összeadás, kivonásnál és bitmanipulációknál bonyolultabb utasítás nincs benne benne (ADC, SBB és CMOVcc viszont elég sok van), a skálázott memóriahozzáférést sem használom már ki, viszont egy pointer-rel két adatterületet is címzek, egyet-egyet a pozitív és a negatív oldalán.

                          pushad
                          lea edx,[ebp*08h]
                          mov ebx,offset(MARKS)
                          xor ecx,ecx
                          lea edi,[ebx+ebp*04h]
                          imul ebp,BYTE(-4)
                          @mark0:
                          sub edx,04h
                          mov [ebx+edx],ecx
                          jg @mark0
                          @@REDUCE_ROWS:
                          mov ebx,ebp
                          @rowmin:
                          mov esi,01000000h
                          mov ecx,ebp
                          xor edx,edx
                          @findrowmin:
                          cmp esi,[eax]
                          cmovz edx,ecx
                          cmova esi,[eax]
                          add ecx,04h
                          lea eax,[eax+04h]
                          jnz @findrowmin
                          sub ecx,ebp
                          cmp esi,01000000h
                          jz @specific
                          add eax,ebp
                          @subrow:
                          xor edx,edx
                          cmp byte ptr [eax+03h],00h
                          cmovz edx,esi
                          sub [eax],edx
                          sub ecx,04h
                          lea eax,[eax+04h]
                          jnz @subrow
                          jmp @reducenxrow
                          @specific:
                          test edx,edx
                          jz @@ABNORMAL_EXIT
                          bts dword ptr [edi+edx],00h
                          jnc @mark
                          @@ABNORMAL_EXIT:
                          add esp,20h
                          xor eax,eax
                          mov edx,7FFFFFFFh
                          stc
                          ret
                          @mark:
                          add ecx,ebx
                          sub dword ptr [esp+__SYS0],01h
                          mov byte ptr [edi+ebx+02h],01h
                          mov [edi+ecx],edx
                          jz @count_result_STACK
                          @reducenxrow:
                          add ebx,04h
                          jnz @rowmin
                          @@RECUDE_COLUMNS:
                          sub ebx,04h
                          sub eax,04h
                          cmp ebx,ebp
                          jl @@2ND_STEP
                          test byte ptr [edi+ebx],01h
                          jnz @@RECUDE_COLUMNS
                          mov edx,01000000h
                          mov ecx,ebp
                          @findcolmin:
                          cmp edx,[eax]
                          cmova edx,[eax]
                          add eax,ebp
                          add ecx,04h
                          jnz @findcolmin
                          cmp edx,01000000h
                          lea ecx,[ebp-04h]
                          jz @@ABNORMAL_EXIT
                          @subcol:
                          xor esi,esi
                          add ecx,04h
                          jz @@RECUDE_COLUMNS
                          sub eax,ebp
                          cmp byte ptr [eax+03h],00h
                          cmovz esi,edx
                          sub [eax],esi
                          jnz @subcol
                          bts dword ptr [edi+ecx],10h
                          jc @subcol
                          bts dword ptr [edi+ebx],00h
                          mov esi,ecx
                          jc @subcol
                          sub esi,ebp
                          sub dword ptr [esp+__SYS0],01h
                          mov byte ptr [eax+03h],01h
                          mov [edi+esi],ebx
                          jnz @subcol
                          jmp @count_result_STACK
                          @@3RD_STEP:
                          mov byte ptr [esi+03h],02h
                          mov byte ptr [edi+ebx+01h],01h
                          mov byte ptr [edi+edx],00h
                          @@2ND_STEP:
                          mov esi,[esp+__MTX]
                          sub esp,20h
                          mov eax,ebp
                          mov edx,00FFFFFFh
                          @nx2row:
                          mov bh,[edi+eax+01h]
                          mov ecx,ebp
                          @zeroinrow:
                          mov bl,[edi+ecx]
                          and bl,01h
                          cmp edx,[esi]
                          adc bl,[edi+eax+01h]
                          jnz @nx2col
                          xor edx,edx
                          add esp,20h
                          add edx,[esi]
                          jz @@DECIDE_NEXT_STEP
                          pushad
                          @nx2col:
                          add ecx,04h
                          lea esi,[esi+04h]
                          jnz @zeroinrow
                          add eax,04h
                          jnz @nx2row
                          @@5TH_STEP:
                          mov ebx,ebp
                          mov esi,[esp+_SAVE+__MTX]
                          @nx5row:
                          cmp byte ptr [edi+ebx+01h],00h
                          mov ecx,ebp
                          jnz @increase_double_markeds
                          @decrease_row_free:
                          bt dword ptr [edi+ecx],00h
                          mov al,[esi+03h]
                          adc al,00h
                          mov eax,00000000h
                          cmovz eax,edx
                          sub [esi],eax
                          add ecx,04h
                          lea esi,[esi+04h]
                          jnz @decrease_row_free
                          jmp @step5row
                          @increase_double_markeds:
                          mov al,[esi+03h]
                          and al,11111100b
                          bt dword ptr [edi+ecx],00h
                          sbb al,00h
                          mov eax,00000000h
                          cmovc eax,edx
                          add [esi],eax
                          add ecx,04h
                          lea esi,[esi+04h]
                          jnz @increase_double_markeds
                          @step5row:
                          add ebx,04h
                          jnz @nx5row
                          popad
                          xor edx,edx
                          @@DECIDE_NEXT_STEP:
                          mov ebx,eax
                          sub eax,ebp
                          add edx,[edi+eax]
                          jnz @@3RD_STEP
                          @@4TH_STEP:
                          mov edx,[esp+__MTX]
                          @colon_to_star:
                          mov [edi+eax],ecx
                          sub ecx,ebp
                          mov byte ptr [esi+03h],01h
                          lea esi,[edx+ecx]
                          mov eax,ebp
                          mov byte ptr [edi+ebx+01h],00h
                          @search_star_in_column:
                          test byte ptr [esi+03h],01h
                          jz @nxstar
                          cmp eax,ebx
                          jnz @0_star
                          @nxstar:
                          sub esi,ebp
                          add eax,04h
                          jnz @search_star_in_column
                          jmp @@1ST_STEP
                          @0_star:
                          mov ebx,eax
                          mov byte ptr [esi+03h],00h
                          sub eax,ebp
                          sub esi,ecx
                          mov dword ptr [edi+eax],00000000h
                          mov ecx,ebp
                          @search_colon_in_row:
                          test byte ptr [esi+03h],02h
                          jnz @colon_to_star
                          add ecx,04h
                          lea esi,[esi+04h]
                          jnz @search_colon_in_row
                          @error:
                          nop
                          @@1ST_STEP:
                          sub dword ptr [esp+__SYS0],01h
                          jz @count_result_STACK
                          mov ebx,ebp
                          mov ecx,[edi+00h]
                          jmp @nxclear
                          @clear_colon:
                          and byte ptr [esi+03h],11111101b
                          add eax,04h
                          lea esi,[esi+04h]
                          jnz @clear_colon
                          @nxclear:
                          mov eax,ebp
                          @markedrow:
                          cmp byte ptr [edi+ebx+01h],00h
                          mov esi,edx
                          mov dword ptr [edi+ebx],00000000h
                          jnz @clear_colon
                          sub edx,ebp
                          add ebx,04h
                          jnz @markedrow
                          @markcol:
                          mov edx,[edi+ebx]
                          add eax,04h
                          lea ebx,[ebx+04h]
                          mov byte ptr [edi+edx],01h
                          jnz @markcol
                          mov [edi+00h],ecx
                          jmp @@2ND_STEP
                          @count_result_STACK:
                          xor ecx,ecx
                          neg ebp
                          xor eax,eax
                          mov esi,[esp+__SAVE]
                          mov ebx,[esp+__MARKS]
                          add esp,20h
                          @results:
                          mov edx,[edi+ecx]
                          add ecx,04h
                          add edx,ebp
                          add eax,[esi+edx]
                          shr edx,02h
                          add esi,ebp
                          cmp ecx,ebp
                          mov [ebx],dl
                          lea ebx,[ebx+01h]
                          jnz @results

                          [ Szerkesztve ]

                          (#35) P.H.


                            P.H.
                            (senior tag)

                            Korrekció: benne maradt néhány letiltott utasítás.
                            A @@2ND_STEP így néz ki:

                            @@2ND_STEP:
                            mov esi,[esp+__MTX]
                            sub esp,20h
                            mov eax,ebp
                            mov edx,00FFFFFFh
                            @nx2row:
                            mov ecx,ebp
                            @zeroinrow:
                            mov bl,[edi+ecx]
                            cmp edx,[esi]
                            adc bl,[edi+eax+01h]
                            jnz @nx2col
                            xor edx,edx
                            add esp,20h
                            add edx,[esi]
                            jz @@DECIDE_NEXT_STEP
                            pushad
                            @nx2col:
                            add ecx,04h
                            lea esi,[esi+04h]
                            jnz @zeroinrow
                            add eax,04h
                            jnz @nx2row

                            (#36) P.H.


                              P.H.
                              (senior tag)

                              - a VectorPath PUSHAD kiváltható 3 tárolással
                              - a @@2ND_STEP-ben levő, körülugrált kicsi valószínűségű ág máshová került
                              - plusz 2 utasítás többletadminisztációval 2 keresőciklus feleslegessé vált
                              - a sorok és oszlopok, valamint a speciális mátrixelemek jelölő byte-értékeinek összehangolása után (mely érték 1, azaz közvetlenül másoható Carry Flag-be BT-vel regiszterhasználat nélkül; mely jelölések összege milyen esetekben pontosan 0) a @@5TH_STEP fele feleslegessé vált

                              2.0 IPC-vel, 36 25x25 mátrix-ot old meg ezredmásodpercenként.

                              pushad
                              shl ebp,02h
                              mov ebx,offset(MARKS)
                              xor ecx,ecx
                              lea edx,[ebp+ebp*02h]
                              lea edi,[ebx+ebp]
                              neg ebp
                              @mark0:
                              sub edx,04h
                              mov [ebx+edx],ecx
                              jg @mark0
                              @@REDUCE_ROWS:
                              mov ebx,ebp
                              @rowmin:
                              mov esi,02000000h
                              mov ecx,ebp
                              xor edx,edx
                              @findrowmin:
                              cmp esi,[eax]
                              cmovz edx,ecx
                              cmova esi,[eax]
                              add ecx,04h
                              lea eax,[eax+04h]
                              jnz @findrowmin
                              sub ecx,ebp
                              cmp esi,02000000h
                              jz @specific
                              add eax,ebp
                              @subrow:
                              xor edx,edx
                              cmp byte ptr [eax+03h],00h
                              cmovz edx,esi
                              sub [eax],edx
                              sub ecx,04h
                              lea eax,[eax+04h]
                              jnz @subrow
                              jmp @reducenxrow
                              @specific:
                              test edx,edx
                              jz @@ABNORMAL_EXIT
                              bts dword ptr [edi+edx],00h
                              jnc @mark
                              @@ABNORMAL_EXIT:
                              add esp,20h
                              xor eax,eax
                              mov edx,7FFFFFFFh
                              stc
                              ret
                              @mark:
                              add ecx,ebx
                              sub dword ptr [esp+__SYS0],01h
                              mov byte ptr [edi+ebx+02h],01h
                              mov [edi+ecx*02h+__0STAR],edx
                              jz @count_result_STACK
                              @reducenxrow:
                              add ebx,04h
                              jnz @rowmin
                              @@RECUDE_COLUMNS:
                              sub ebx,04h
                              sub eax,04h
                              cmp ebx,ebp
                              jl @@2ND_STEP
                              test byte ptr [edi+ebx],01h
                              jnz @@RECUDE_COLUMNS
                              mov edx,02000000h
                              mov ecx,ebp
                              @findcolmin:
                              cmp edx,[eax]
                              cmova edx,[eax]
                              add eax,ebp
                              add ecx,04h
                              jnz @findcolmin
                              cmp edx,02000000h
                              lea ecx,[ebp-04h]
                              jz @@ABNORMAL_EXIT
                              @subcol:
                              xor esi,esi
                              add ecx,04h
                              jz @@RECUDE_COLUMNS
                              sub eax,ebp
                              cmp byte ptr [eax+03h],00h
                              cmovz esi,edx
                              sub [eax],esi
                              jnz @subcol
                              bts dword ptr [edi+ecx],10h
                              jc @subcol
                              bts dword ptr [edi+ebx],00h
                              mov esi,ecx
                              jc @subcol
                              sub esi,ebp
                              sub dword ptr [esp+__SYS0],01h
                              mov byte ptr [eax+03h],02h
                              mov [edi+esi*02h+__0STAR],ebx
                              jnz @subcol
                              jmp @count_result_STACK

                              @@3RD_STEP:
                              mov byte ptr [esi+03h],08h
                              mov byte ptr [edi+ebx+01h],0FFh
                              mov byte ptr [edi+edx],00h
                              mov [edi+eax*02h+__COLON],ecx
                              @@2ND_STEP:
                              mov eax,ebp
                              mov edx,00FFFFFFh
                              mov esi,[esp+__MTX]
                              @nx2row:
                              mov ecx,ebp
                              mov bh,[edi+eax+01h]
                              @zeroinrow:
                              cmp edx,[esi]
                              mov bl,bh
                              sbb bl,[edi+ecx]
                              jz @minimum
                              @nx2col:
                              add ecx,04h
                              lea esi,[esi+04h]
                              jnz @zeroinrow
                              add eax,04h
                              jnz @nx2row
                              @@5TH_STEP:
                              mov ebx,ebp
                              mov esi,[esp+__MTX]
                              @nx5row:
                              movsx eax,byte ptr [edi+ebx+01h]
                              mov ecx,ebp
                              xor eax,edx
                              jns @decrease_row_free
                              neg edx
                              @decrease_row_free:
                              bt dword ptr [edi+ecx],00h
                              mov al,[esi+03h]
                              adc al,[edi+ebx+01h]
                              mov eax,00000000h
                              cmovz eax,edx
                              sub [esi],eax
                              add esi,04h
                              add ecx,04h
                              jnz @decrease_row_free
                              add ebx,04h
                              jnz @nx5row
                              mov eax,[esp+__FREE0ROW]
                              xor edx,edx
                              mov ecx,[esp+__FREE0COL]
                              mov esi,[esp+__FREE0]
                              jmp @@DECIDE_NEXT_STEP
                              @minimum:
                              xor edx,edx
                              mov [esp+__FREE0ROW],eax
                              add edx,[esi]
                              mov [esp+__FREE0COL],ecx
                              mov [esp+__FREE0],esi
                              jnz @nx2col
                              @@DECIDE_NEXT_STEP:
                              mov ebx,eax
                              sub eax,ebp
                              add edx,[edi+eax*02h+__0STAR]
                              jnz @@3RD_STEP
                              @@4TH_STEP:
                              mov edx,[esp+__MTX]
                              jmp @colon_to_star
                              @0_star:
                              mov ebx,eax
                              mov byte ptr [esi+03h],00h
                              sub esi,ecx
                              sub eax,ebp
                              sub esi,ebp
                              mov ecx,[edi+eax*02h+__COLON]
                              lea esi,[esi+ecx]
                              @colon_to_star:
                              mov [edi+eax*02h+__0STAR],ecx
                              sub ecx,ebp
                              mov byte ptr [esi+03h],02h
                              lea esi,[edx+ecx]
                              mov eax,ebp
                              @search_star_in_column:
                              test byte ptr [esi+03h],02h
                              jz @nxstar
                              cmp eax,ebx
                              jnz @0_star
                              @nxstar:
                              sub esi,ebp
                              add eax,04h
                              jnz @search_star_in_column
                              @@1ST_STEP:
                              sub dword ptr [esp+__SYS0],01h
                              lea ebx,[edi+__COLON]
                              mov ecx,ebp
                              jz @count_result_STACK
                              @restructure:
                              mov esi,[ebx]
                              sub edx,ebp
                              mov [edi+ecx],eax
                              and byte ptr [edx+esi+03h],11110111b
                              add ecx,04h
                              mov [ebx],eax
                              lea ebx,[ebx+08h]
                              jnz @restructure
                              mov ebx,edi
                              mov eax,ebp
                              mov ecx,[edi+00h]
                              @markcol:
                              mov edx,[ebx+__0STAR]
                              add eax,04h
                              lea ebx,[ebx+08h]
                              mov byte ptr [edi+edx],01h
                              jnz @markcol
                              mov [edi+00h],ecx
                              jmp @@2ND_STEP
                              @count_result_STACK:
                              xor ecx,ecx
                              neg ebp
                              xor eax,eax
                              mov esi,[esp+__SAVE]
                              mov ebx,[esp+__MARKS]
                              add esp,20h
                              @results:
                              mov edx,[edi+ecx*02h+__0STAR]
                              add ecx,04h
                              add edx,ebp
                              add eax,[esi+edx]
                              shr edx,02h
                              add esi,ebp
                              cmp ecx,ebp
                              mov [ebx],dl
                              lea ebx,[ebx+01h]
                              jnz @results

                              (#37) P.H.


                                P.H.
                                (senior tag)

                                Az 5. és az 1. lépés finomhangolása után, valamint a munkaterület címe bemeneti paraméter lett (a hívó algoritmus többszálúsítása okán):

                                2.0 IPC-vel, 38 25x25 mátrix-ot old meg ezredmásodpercenként.

                                pushad
                                shl ebp,02h
                                xor ecx,ecx
                                lea edx,[ebp+ebp*02h]
                                lea edi,[ebx+ebp]
                                neg ebp
                                @mark0:
                                sub edx,04h
                                mov [ebx+edx],ecx
                                jg @mark0
                                @@REDUCE_ROWS:
                                mov ebx,ebp
                                @rowmin:
                                mov esi,02000000h
                                mov ecx,ebp
                                xor edx,edx
                                @findrowmin:
                                cmp esi,[eax]
                                cmovz edx,ecx
                                cmova esi,[eax]
                                add ecx,04h
                                lea eax,[eax+04h]
                                jnz @findrowmin
                                sub ecx,ebp
                                cmp esi,02000000h
                                jz @specific
                                add eax,ebp
                                @subrow:
                                xor edx,edx
                                cmp byte ptr [eax+03h],00h
                                cmovz edx,esi
                                sub [eax],edx
                                sub ecx,04h
                                lea eax,[eax+04h]
                                jnz @subrow
                                jmp @reducenxrow
                                @specific:
                                test edx,edx
                                jz @@ABNORMAL_EXIT
                                bts dword ptr [edi+edx],00h
                                jnc @mark
                                @@ABNORMAL_EXIT:
                                add esp,20h
                                xor eax,eax
                                mov edx,7FFFFFFFh
                                stc
                                ret
                                @mark:
                                add ecx,ebx
                                sub dword ptr [esp+__SYS0],01h
                                mov byte ptr [edi+ebx+02h],01h
                                mov [edi+ecx*02h+__0STAR],edx
                                jz @count_result_STACK
                                @reducenxrow:
                                add ebx,04h
                                jnz @rowmin
                                @@RECUDE_COLUMNS:
                                sub ebx,04h
                                sub eax,04h
                                cmp ebx,ebp
                                jl @@2ND_STEP
                                test byte ptr [edi+ebx],01h
                                jnz @@RECUDE_COLUMNS
                                mov edx,02000000h
                                mov ecx,ebp
                                @findcolmin:
                                cmp edx,[eax]
                                cmova edx,[eax]
                                add eax,ebp
                                add ecx,04h
                                jnz @findcolmin
                                cmp edx,02000000h
                                lea ecx,[ebp-04h]
                                jz @@ABNORMAL_EXIT
                                @subcol:
                                xor esi,esi
                                add ecx,04h
                                jz @@RECUDE_COLUMNS
                                sub eax,ebp
                                cmp byte ptr [eax+03h],00h
                                cmovz esi,edx
                                sub [eax],esi
                                jnz @subcol
                                bts dword ptr [edi+ecx],10h
                                jc @subcol
                                bts dword ptr [edi+ebx],00h
                                mov esi,ecx
                                jc @subcol
                                sub esi,ebp
                                sub dword ptr [esp+__SYS0],01h
                                mov byte ptr [eax+03h],02h
                                mov [edi+esi*02h+__0STAR],ebx
                                jnz @subcol
                                jmp @count_result_STACK

                                @@3RD_STEP:
                                mov byte ptr [esi+03h],08h
                                mov byte ptr [edi+ebx+03h],0FFh
                                mov byte ptr [edi+edx],00h
                                mov [edi+eax*02h+__COLON],ecx
                                @@2ND_STEP:
                                mov eax,ebp
                                mov esi,[esp+__MTX]
                                mov edx,00FFFFFFh
                                @nx2row:
                                mov bh,[edi+eax+03h]
                                mov ecx,ebp
                                @zeroinrow:
                                cmp edx,[esi]
                                mov bl,bh
                                sbb bl,[edi+ecx]
                                jz @minimum
                                @nx2col:
                                add ecx,04h
                                lea esi,[esi+04h]
                                jnz @zeroinrow
                                add eax,04h
                                jnz @nx2row
                                @@5TH_STEP:
                                mov ebx,ebp
                                mov esi,[esp+__MTX]
                                @nx5row:
                                mov eax,edx
                                sub ecx,edx
                                xor eax,[edi+ebx]
                                cmovs edx,ecx
                                mov ecx,ebp
                                @decrease_row_free:
                                bt dword ptr [edi+ecx],00h
                                mov al,[esi+03h]
                                adc al,[edi+ebx+03h]
                                mov eax,00000000h
                                cmovz eax,edx
                                sub [esi],eax
                                add esi,04h
                                add ecx,04h
                                jnz @decrease_row_free
                                add ebx,04h
                                jnz @nx5row
                                mov eax,[esp+__FREE0ROW]
                                xor edx,edx
                                mov ecx,[esp+__FREE0COL]
                                mov esi,[esp+__FREE0]
                                jmp @@DECIDE_NEXT_STEP
                                @minimum:
                                xor edx,edx
                                mov [esp+__FREE0ROW],eax
                                add edx,[esi]
                                mov [esp+__FREE0COL],ecx
                                mov [esp+__FREE0],esi
                                jnz @nx2col
                                @@DECIDE_NEXT_STEP:
                                mov ebx,eax
                                sub eax,ebp
                                add edx,[edi+eax*02h+__0STAR]
                                jnz @@3RD_STEP
                                @@4TH_STEP:
                                mov edx,[esp+__MTX]
                                jmp @colon_to_star
                                @0_star:
                                mov ebx,eax
                                mov byte ptr [esi+03h],00h
                                sub esi,ecx
                                sub eax,ebp
                                sub esi,ebp
                                mov ecx,[edi+eax*02h+__COLON]
                                lea esi,[esi+ecx]
                                @colon_to_star:
                                mov [edi+eax*02h+__0STAR],ecx
                                sub ecx,ebp
                                mov byte ptr [esi+03h],02h
                                lea esi,[edx+ecx]
                                mov eax,ebp
                                @search_star_in_column:
                                cmp eax,ebx
                                jz @nxstar
                                test byte ptr [esi+03h],02h
                                jnz @0_star
                                @nxstar:
                                sub esi,ebp
                                add eax,04h
                                jnz @search_star_in_column
                                @@1ST_STEP:
                                sub dword ptr [esp+__SYS0],01h
                                mov ecx,ebp
                                mov ebx,edi
                                jz @count_result_STACK
                                push dword ptr [edi]
                                @restructure:
                                mov esi,[ebx+__COLON]
                                sub edx,ebp
                                mov [edi+ecx+03h],al
                                and byte ptr [edx+esi+03h],11110111b
                                mov esi,[ebx+__0STAR]
                                add ecx,04h
                                mov [ebx+__COLON],eax
                                lea ebx,[ebx+08h]
                                mov byte ptr [edi+esi],01h
                                jnz @restructure
                                pop dword ptr [edi]
                                jmp @@2ND_STEP
                                @count_result_STACK:
                                xor ecx,ecx
                                neg ebp
                                xor eax,eax
                                mov esi,[esp+__SAVE]
                                mov ebx,[esp+__MARKS]
                                add esp,20h
                                @results:
                                mov edx,[edi+ecx*02h+__0STAR]
                                add ecx,04h
                                add edx,ebp
                                add eax,[esi+edx]
                                shr edx,02h
                                add esi,ebp
                                cmp ecx,ebp
                                mov [ebx],dl
                                lea ebx,[ebx+01h]
                                jnz @results

                                [ Szerkesztve ]

                                (#38) P.H.


                                  P.H.
                                  (senior tag)

                                  1 GHz-es Brazos (max. 2 utasítás/órajel micro-arch) az utoljára írt kóddal: átlagosan 1.5 IPC

                                  PerfMonitor Record file
                                  Counter 0 : Non-halted clock cycles
                                  Counter 1 : Retired uops
                                  Counter 2 : Instructions per cycle (IPC)
                                  Counter 3 : L1 Data cache misses

                                  65950 881.3 1379.8 1.6 0.2
                                  66000 821.5 1163.5 1.4 0.5
                                  66050 820.2 1261.3 1.5 0.3
                                  66100 737.5 994.7 1.3 0.8
                                  66150 737.5 994.7 1.3 0.8
                                  66200 842.2 1192.9 1.4 0.7
                                  66250 801.5 1210.0 1.5 0.3
                                  66300 767.6 994.4 1.3 1.1
                                  66350 840.1 1273.6 1.5 0.3
                                  66400 855.2 1334.0 1.6 0.3
                                  66450 823.4 1196.1 1.4 0.7
                                  66500 733.6 1016.0 1.4 0.7
                                  66550 787.5 1134.9 1.4 0.6
                                  66600 828.6 1204.5 1.4 0.5
                                  66650 909.5 1380.5 1.5 0.4
                                  66700 781.3 1157.5 1.5 0.5
                                  66750 816.6 1163.7 1.4 0.6
                                  66800 805.0 1149.6 1.4 0.6
                                  66850 777.0 1089.3 1.4 0.6
                                  66900 815.3 1205.9 1.5 0.5
                                  66950 804.8 1222.9 1.5 0.4
                                  67000 790.1 1026.5 1.3 0.7
                                  67050 737.5 983.0 1.3 0.8
                                  67100 826.8 1275.2 1.5 0.3
                                  67150 795.9 1153.1 1.4 0.6
                                  67200 760.8 1068.4 1.4 0.6
                                  67250 822.5 1218.7 1.5 0.5
                                  67300 828.5 1223.5 1.5 0.5
                                  67350 817.5 1150.6 1.4 0.4
                                  67400 811.8 1214.2 1.5 0.4
                                  67450 755.6 1051.2 1.4 0.7
                                  67500 858.5 1315.3 1.5 0.4
                                  67550 754.6 1080.0 1.4 0.6
                                  67600 863.4 1195.5 1.4 0.6
                                  67650 750.7 1065.4 1.4 0.6

                                  [ Szerkesztve ]

                                  (#39) P.H.


                                    P.H.
                                    (senior tag)

                                    SSE1 line algoritmus azonos stílusú vonalak láncolt listájára + 1st gen. Nerburst és K10 port elemzés:
                                    (»port latency (uops) subunit« formában)

                                    K10-en kb. 10%-kal gyorsabb, mint az x87-es megvalósítás, Prescott-on a sebességnövekedés több, mint kétszeres az x87-hez képest.
                                    K10-en 1.6 IPC mérhető (kb. 30000 vonalas tesztadaton 10,5M órajel), Netburst-re visszaszámolva (ugyanazon a tesztadaton 26M órajel) 0.65 IPC.

                                    mov ecx,[esi+_DATA1] // p2 2 (1) load p012 3 (1) AGU
                                    pushad // -vector- -vector-
                                    xorps xmm0,xmm0 // p1 2 (1) mmxalu p34 2 (1) FA/M
                                    lea edi,[esi+DATA2] // p0/1 d (1) alu p012 3 (1) AGU
                                    pcmpeqw xmm7,xmm7 // p1 2 (1) mmxalu p34 2 (1) FA/M
                                    cvtpi2ps xmm3,[edi-...+_TOPLEFT] // p1+2 10 (4) mmx+load 7 (2)
                                    xorps xmm1,xmm1 // p1 2 (1) mmxalu p34 2 (1) FA/M
                                    mov esi,[esi+...DEST] // p2 2 (1) load p012 3 (1) AGU
                                    pslld xmm7,1Fh // p1 2 (1) mmxshf p34 3 (1) FA/M
                                    cvtpi2ps xmm2,[edi-...+_RIGHTBOTTOM] // p1+2 10 (4) mmx+load 7 (2)
                                    xorps xmm5,xmm5 // p1 2 (1) mmxalu p34 2 (1) FA/M
                                    shufps xmm3,xmm2,01000000b // p1 4 (1) mmxshf p34 3 (1) FA/M
                                    sub edi,ecx // p0/1 d (1) alu p012 1 (1) ALU
                                    xorps xmm6,xmm6 // p1 2 (1) mmxalu p34 2 (1) FA/M
                                    shufps xmm3,xmm3,11011000b // p1 4 (1) mmxshf p34 3 (1) FA/M
                                    @nxline:
                                    test ebx,ebx // p0/1 d (1) alu p012 1 (1) ALU
                                    jz @return // p0 2 (1) alu p012 1 (1) ALU
                                    mov eax,[ebx+TRECORD.REF] // p2 2 (1) load p012 3 (1) AGU
                                    pcmpeqw xmm2,xmm2 // p1 2 (1) mmxalu p34 2 (1) FA/M
                                    mov ecx,[ebx+TRECORD.SELF] // p2 2 (1) load p012 3 (1) AGU
                                    mov ebp,[eax+THEADER.YCOOR] // p2 2 (1) load p012 3 (1) AGU
                                    pcmpeqw xmm4,xmm4 // p1 2 (1) mmxalu p34 2 (1) FA/M
                                    mov edx,[ecx+THEADER.YCOOR] // p2 2 (1) load p012 3 (1) AGU
                                    psrld xmm2,01h // p1 2 (1) mmxshf p34 3 (1) FA/M
                                    mov eax,[eax+THEADER.XCOOR] // p2 2 (1) load p012 3 (1) AGU
                                    mov ecx,[ecx+THEADER.XCOOR] // p2 2 (1) load p012 3 (1) AGU
                                    sub ebp,edx // p0/1 d (1) alu p012 1 (1) ALU
                                    movaps xmm6,xmm2 // p0 6 (1) mov p345 3 (1) FANY
                                    sub eax,ecx // p0/1 d (1) alu p012 1 (1) ALU
                                    pslld xmm4,25 // p1 2 (1) mmxshf p34 3 (1) FA/M
                                    cvtsi2ss xmm1,ebp // p1 10 (3) fpmmx 14 (3)
                                    mov ebx,[ebx+TRECORD.NX] // p2 2 (1) load p012 3 (1) AGU
                                    cvtsi2ss xmm0,eax // p1 10 (3) fpmmx 14 (3)
                                    andps xmm6,xmm1 // p1 2 (1) mmxalu p34 2 (1) FA/M
                                    andps xmm2,xmm0 // p1 2 (1) mmxalu p34 2 (1) FA/M
                                    psrld xmm4,02h // p1 2 (1) mmxshf p34 3 (1) FA/M
                                    comiss xmm6,xmm2 // p1 6 (2) fpadd p3 (1) FADD
                                    mov [esp+_EBX],ebx // p0+3 2 (3) alu+store p012 3 (1) AGU
                                    cmovbe ebp,eax // 6 (3) p012 1 (1) ALU
                                    cvtsi2ss xmm6,edx // p1 10 (3) fpmmx 14 (3)
                                    setbe al // p1 5 (3) alu p012 1 (1) ALU
                                    jae @inlineMOVEX // p0 2 (1) alu p012 1 (1) ALU
                                    movaps xmm2,xmm0 // p0 6 (1) mov p345 3 (1) FANY
                                    movaps xmm0,xmm1 // p0 6 (1) mov p345 3 (1) FANY
                                    movaps xmm1,xmm2 // p0 6 (1) mov p345 3 (1) FANY
                                    @inlineMOVEX:
                                    test ebp,ebp // p0/1 d (1) alu p012 1 (1) ALU
                                    cvtsi2ss xmm5,ecx // p1 10 (3) fpmmx 14 (3)
                                    jz @nxline // p0 2 (1) alu p012 1 (1) ALU
                                    divss xmm0,xmm1 // p1 23 (1) fpdiv p4 16 (1) FMUL
                                    mov ebx,[esp+_ECX] // p2 2 (1) load p012 3 (1) AGU
                                    shufps xmm4,xmm0,00000000b // p1 4 (1) mmxshf p34 3 (1) FA/M
                                    jns @inlineSETDIR // p0 2 (1) alu p012 1 (1) ALU
                                    neg ebp // p0 d (1) alu p012 1 (1) ALU
                                    xorps xmm4,xmm7 // p1 2 (1) mmxalu p34 2 (1) FA/M
                                    @inlineSETDIR:
                                    test al,al // p0/1 d (1) alu p012 1 (1) ALU
                                    mov al,[edi+ebx-_ADDER+_DRAWCOLOR] // p2 2 (1) load p012 3 (1) AGU
                                    shufps xmm5,xmm6,00000000h // p1 4 (1) mmxshf p34 3 (1) FA/M
                                    jnz @setpixel // p0 2 (1) alu p012 1 (1) ALU
                                    shufps xmm4,xmm4,00001010b // p1 4 (1) mmxshf p34 3 (1) FA/M
                                    @setpixel:
                                    movaps xmm2,xmm3 // p0 6 (1) mov p345 3 (1) FANY
                                    imul edx,[edi+ebx-_ADDER+_DX] // p1+2 15 (4) fpmul+load p0 6 (1) ALU0+AGU
                                    cmpltps xmm2,xmm5 // p1 4 (1) fpadd p3 (1) FADD
                                    add edx,ecx // p0/1 d (1) alu p012 1 (1) ALU
                                    addps xmm5,xmm4 // p1 4 (1) fpadd p3 4 (1) FADD
                                    movmskps ecx,xmm2 // p1 6 (2) fp p34 3 (1) FA/M
                                    movhlps xmm0,xmm5 // p1 4 (1) mmxshf
                                    cmp cl,05h // p0/1 d (1) alu p012 1 (1) ALU
                                    cvtss2si ecx,xmm5 // p1 8 (2) fp p3+5 8 (2) FADD+FMISC
                                    jnz @continueLINE // p0 2 (1) alu p012 1 (1) ALU
                                    @round:
                                    add edx,[edi+ebx] // p1+2 d (2) alu+load p012 4 (2) ALU+AGU
                                    add ebx,04h // p0/1 d (1) alu p012 1 (1) ALU
                                    mov [esi+edx],al // p0+3 2 (3) store p012 3 (1) AGU
                                    js @round // p0 2 (1) alu p012 1 (1) ALU
                                    mov ebx,[esp+_ECX] // p2 2 (1) load p012 3 (1) AGU
                                    @continueLINE:
                                    sub ebp,01h // p01 d (1) alu p012 1 (1) ALU
                                    cvtss2si edx,xmm0 // p1 8 (2) fp p3+5 8 (2) FADD+FMISC
                                    jge @setpixel // p0 2 (1) alu p012 1 (1) ALU
                                    mov ebx,[esp+_EBX] // p2 2 (1) load p012 3 (1) AGU
                                    jmp @nxline // p1 0 (1) alu p012 1 (2) ALU
                                    @return:
                                    popad // -vector- -vector-

                                    [ Szerkesztve ]

                                    (#40) P.H.


                                      P.H.
                                      (senior tag)

                                      Gyors o(log n) rendezési algoritmus 64 bites lebegőpontos számokra:

                                      inicializálás:
                                      kimenet:
                                      ESI: az ideiglenes,32 bites elemekből álló munkatömb címe
                                      EDI: a 32 bites munkatömb mérete
                                      bemenet:
                                      EAX: a 64 bites számok tömbjére mutató pointer
                                      EDX: az értékek száma a tömbben
                                      ESI: az ideiglenes,32 bites elemekből álló munkatömb címe
                                      lea edx,[eax+edx*08h]
                                      fldz
                                      mov ecx,esi
                                      xor edi,edi
                                      @insert:
                                      mov [ecx],edx
                                      sub edx,08h
                                      lea ebp,[edi+01h]
                                      cmp edx,[esp+_EAX]
                                      fstp st(0)
                                      jbe @return
                                      add edi,01h
                                      fld qword ptr [edx]
                                      @moveup:
                                      lea ecx,[esi+ebp*04h]
                                      shr ebp,01h
                                      mov ebx,[esi+ebp*04h]
                                      jz @insert
                                      fcom qword ptr [ebx]; fnstsw ax; sahf
                                      jae @insert
                                      mov [ecx],ebx
                                      jmp @moveup
                                      @return:

                                      A következő legkisebb elem lehívása:
                                      kimenet:
                                      EDX: a legkisebb elem pozíciója az eredeti tömmben
                                      EDI: a 32 bites munkatömb új mérete
                                      bemenet:
                                      EAX: a 64 bites számok tömbjére mutató pointer
                                      EDI: a 32 bites munkatömb jelenlegi mérete
                                      ESI: az ideiglenes,32 bites elemekből álló munkatömb címe
                                      or edx,-1
                                      sub edi,01h
                                      js @invalid
                                      pushad
                                      mov edx,[esi+01h*04h]
                                      mov ebp,00000001h
                                      mov ecx,[esi+edi*04h+04h]
                                      fld qword ptr [edx]
                                      sub edx,eax
                                      fld qword ptr [ecx]
                                      mov [esp+_EDX],edx
                                      @down:
                                      mov edx,ebp
                                      lea eax,[esi+ebp*(04h*2)]
                                      add ebp,ebp
                                      cmp ebp,edi
                                      ja @insertdown
                                      mov ebx,[eax+00h]
                                      mov edx,[eax+04h]
                                      jz @child
                                      fld qword ptr [edx]
                                      fcomp qword ptr [ebx]; fnstsw ax; sahf
                                      cmovb ebx,edx {cmovb = cmovc}
                                      adc ebp,00h
                                      @child:
                                      fcom qword ptr [ebx]
                                      mov edx,ebp
                                      fnstsw ax
                                      shr edx,01h
                                      sahf
                                      mov [esi+edx*04h],ebx
                                      ja @down
                                      @insertdown:
                                      fstp st(0)
                                      mov [esi+edx*04h],ecx
                                      popad
                                      sar edx,03h
                                      @invalid:
                                      popad

                                      A rendezés végét a negatív (-1) visszaadott pozíció jelzi, nem szükséges tesztelni a lépések számát.

                                      [ Szerkesztve ]

                                      üzenetek