Keresés

Aktív témák

  • P.H.

    senior tag

    válasz P.H. #3 üzenetére

    Update:

    K8:
    - előkészített REP STOSD: 153M órajel
    - @unpackSSE2 (movnti [edi],eax): 68M órajel
    - @unpack (mov [edi],eax): 62M órajel
    Netburst (Prescott):
    - előkészített REP STOSD: 410M órajel
    - @unpackSSE2 (movnti [edi],eax): 110M órajel
    - @unpack (mov [edi],eax): 150M órajel

    Ez némi gondolkodnivalót ad a VectorPath, illetve úgy általában a microcode alapú utasításokról. A REP STOSD legrosszabb esetben is egyenértékű a

    @stosd:
    jcxz @done
    dec ecx
    mov [edi],eax
    lea edi,[edi+04h]
    jmp @stosd
    @done:

    sorozattal akár micro-op szinten is: a "service pending interrupts (if any);" lépést és (a debugger-ek tanulsága szerint) ESP-t befolyásoló ugrást mindkettő tartalmaz. A microcode-on alapuló utasítások micro-opjai a microarchitecture szélességére optimalizáltak, de mennyi az az ismétlésmennyiség, aminél a REP STOSD gyorsabb, mint a klasszikus legalapvetőbb egyszerű ciklus? Van egyáltalán ilyen eset?

    [ Szerkesztve ]

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #6 üzenetére

    hotfix:

    { EAX: src0 string address
    EDX: src1 string address }
    pushad
    xor esi,esi
    xor edi,edi
    mov ebx,offset(_uppercase)
    add esi,eax
    jz @finalize
    add edi,edx
    jz @finalize
    @compare:
    xor eax,eax
    xor edx,edx
    xor ecx,ecx
    add al,[esi]
    lea esi[esi+01h]
    mov dl,[edi]
    mov al,[ebx+eax]
    jz @final
    add cl,[ebx+edx]
    lea edi,[edi+01h]
    jz @finalize
    cmp al,cl
    mov dl,cl
    jz @compare
    @finalize:
    cmp eax,edx
    popad
    setz al ; elhagyható ASM szinten
    ret

    A "viszont a kisebb/nagyobb relációt is az EFLAGS-ben" törölve (_uppercase átszerkesztés kell hozzá, mert z<ő)

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #12 üzenetére

    hotfix:

    Ennek ellentmond, hogy a (dinamikusan allokált tömb méretének lekérdezése, ha a tömb nem NULL):

    test eax,eax
    cmovnz eax,[eax-04h]

    kód EAX = 0 esetben védelmi hibával leáll, tehát a cmovcc függ mindkét bemeneti értékétől.

    [ Szerkesztve ]

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #28 üzenetére

    @@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 ]

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #29 üzenetére

    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."

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #39 üzenetére

    a #39-beli összehasonlításban használt vonalankénti x87 kód:

    sub ebp,edx
    sub ecx,eax
    pushad
    lea edi,[esi+...+DATA2]
    fild dword ptr [esp+_ECX]
    shl eax,10h
    fild dword ptr [esp+_EBP]
    mov esi,[esi+...DEST]
    fld st(1)
    mov ebx,[edi-..._DATA1]
    fabs
    fld st(1)
    fabs
    fcompp
    sub edi,ebx
    fnstsw ax
    sahf
    ja @inlineMOVEX
    mov ebp,ecx
    fxch
    @inlineMOVEX:
    test ebp,ebp
    fdiv
    fld1
    jz @return
    jns @inlineSETDIR
    neg ebp
    fchs
    @inlineSETDIR:
    sahf
    fmul st(1),st
    jbe @inlineCOORDINATES
    fxch
    @inlineCOORDINATES:
    fild dword ptr [esp+_EDX]
    sar eax,10h
    fild dword ptr [esp+_EAX]
    @setpixel:
    cmp edx,[edi-...+_TOPLEFT]
    fadd st,st(2)
    setl cl
    cmp edx,[edi-...+_BOTTOM]
    setge ch
    imul edx,[edi-...+_DX]
    or ch,cl
    cmp eax,[edi-...+_RIGHT]
    setge cl
    add edx,eax
    or ch,cl
    cmp eax,[edi-...+_TOPLEFT]
    mov [esp+_ECX],ebx
    setl cl
    mov al,[edi+ebx-_ADDER+_DRAWCOLOR]
    or cl,ch
    jnz @continueLINE
    @round:
    add edx,[edi+ebx]
    add ebx,04h
    mov [esi+edx],al
    js @round
    mov ebx,[esp+_ECX]
    @continueLINE:
    fxch
    fadd st,st(3)
    sub ebp,01h
    fist dword ptr [esp+_ECX]
    fxch
    mov edx,[esp+_ECX]
    fist dword ptr [esp+_ECX]
    mov eax,[esp+_ECX]
    jge @setpixel
    fcompp
    @return:
    popad
    fcompp

    [ Szerkesztve ]

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #46 üzenetére

    Némi módosítással mostmár az elvárható szintet hozza a kód, folyamatosan tartja a 2.4 IPC-t.

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

    1000 2602.3 6239.3 2.4 0.0
    1050 2625.0 6279.9 2.4 0.0
    1100 2622.7 6217.2 2.4 0.0
    1150 2624.9 6212.2 2.4 0.0
    1200 2607.5 6200.2 2.4 0.1
    1250 2626.4 6246.8 2.4 0.0
    1300 2621.9 6223.3 2.4 0.0
    1350 2625.4 6207.1 2.4 0.0
    1400 2607.3 6176.2 2.4 0.1
    1450 2624.8 6223.7 2.4 0.1
    1500 2593.0 6160.8 2.4 0.1
    1550 2625.6 6257.4 2.4 0.1
    1600 2610.2 6214.2 2.4 0.0
    1650 2621.0 6224.5 2.4 0.1
    1700 2621.6 6254.4 2.4 0.0
    1750 2624.4 6201.1 2.4 0.0
    1800 2610.4 6156.3 2.4 0.0
    1850 2625.9 6208.6 2.4 0.0
    1900 2622.2 6224.9 2.4 0.0
    1950 2626.3 6263.7 2.4 0.0
    2000 2610.2 6255.1 2.4 0.1
    2050 2625.3 6284.7 2.4 0.0
    2100 2618.1 6281.4 2.4 0.0
    2150 2601.0 6225.6 2.4 0.1
    2200 2620.6 6289.6 2.4 0.1

    Mivel korábban nem vettem figyelembe, hogy bár a LEA utasítás K10-en és Core2/Nehalem/Sandy Bridge-en 1 órajel, viszont K7/K8-on 2 órajel, Atom-on 4, Prescott-on 2.5, így ezeken nagyon nem egyenértékű a sima összeadással, ezért kivettem a felesleges LEA utasításokat; Prescott-on 10%-kal gyorsult.
    Ennek további hozadéka, hogy mivel a Sandy Bridge már az ADD/SUB + Jcc párokat is tudja egyesíteni (macro-fusion), az Atom szintén tudja párosítani ezeket (én pedig korábban minden ilyen pár közé tettem a LEA utasításokat, mert nem szeretem az egymást közvetlenül követő függő integer-kódokat), ezért szinte minden ciklus profitál ebből mindkettőn.

    Érdekes lesz a Bulldozer, mivel ahhoz, hogy ez a kód 2.4 IPC felett tudjon futni, a következők kellenek:
    1. 3 ALU
    2. legalább 2 load/cycle/thread (pl. a @@5ST_STEP 9 utasításos ciklusában 3 load, 1 load+store, 1 ugrás és 4 regiszter-utasítás van)
    3. CMOVcc, ADC és SBB utasítások végrehajtása 1 órajel alatt
    3. a cikluszáró ADD+Jcc párosok fúziója igencsak gyorsít (szinte minden ciklus így zárul)
    4. a teljes kód elfér egy pár 100 elemű uop cache-ben

    Jelen pillanatban úgy tudni, az első kettővel a Sandy Bridge és a K7-K10 sorozat rendelkezik, a harmadikkal csak a K7-K10, az utolsó 2 pedig a Sandy Bridge sajátja.
    (Elvileg a kód az első 754/939 K8-as generációkon gyorsabb is, mint K10-en, mivel akkor az L1-latency csak 2 órajel volt.)
    A Bulldozer 1. generációjában az első kettő kizárt, a 3. szinte biztos, az utolsó kettő lehetséges, de az eddigi információk nem említik őket. Persze ha a maximum 2.0 IPC/thread megfelelő órajellel párosul, akkor nem lehet gond.

    mov eax,edi
    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
    mov byte ptr [edi+00h],01h
    @@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 eax,04h
    add ecx,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
    add eax,04h
    sub ecx,04h
    jnz @subrow
    add ebx,04h
    jnz @rowmin
    jmp @columns
    @specific:
    cmp byte ptr [edi+edx],00h
    mov byte ptr [edi+edx],01h
    jnz @@ABNORMAL_EXIT
    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
    add ebx,04h
    jnz @rowmin
    @columns:
    mov [edi+00h],bl
    @@RECUDE_COLUMNS:
    sub ebx,04h
    sub eax,04h
    cmp ebx,ebp
    jl @@2ND_STEP
    test byte ptr [edi+ebx],01h
    jnz @@RECUDE_COLUMNS
    mov esi,02000000h
    mov ecx,ebp
    @findcolmin:
    cmp esi,[eax]
    cmova esi,[eax]
    add eax,ebp
    add ecx,04h
    jnz @findcolmin
    cmp esi,02000000h
    lea ecx,[ebp-04h]
    jz @@ABNORMAL_EXIT
    @subcol:
    xor edx,edx
    add ecx,04h
    jz @@RECUDE_COLUMNS
    sub eax,ebp
    cmp [eax+03h],dl
    cmovz edx,esi
    sub [eax],edx
    jnz @subcol
    mov dl,[edi+ecx+02h]
    or dl,[edi+ebx]
    mov edx,ecx
    jnz @subcol
    mov byte ptr [edi+ebx],01h
    sub edx,ebp
    mov byte ptr [edi+ecx+02h],01h
    sub dword ptr [esp+__SYS0],01h
    mov [edi+edx*02h+__0STAR],ebx
    jnz @subcol
    jmp @count_result_STACK
    @@ABNORMAL_EXIT:
    add esp,20h
    xor eax,eax
    mov edx,7FFFFFFFh
    stc
    ret

    { CODE PADDING }

    @@3RD_STEP:
    mov byte ptr [edi+ebx+03h],0FFh
    mov byte ptr [edi+edx],00h
    mov [edi+eax*02h+__COLON],ecx
    @@2ND_STEP:
    {0} lea ecx,[ebp-04h]
    {1} mov edx,00FFFFFFh
    {2} jmp @c2col
    @zeroincol:
    {0} cmp edx,[esi]
    {1} mov bl,[edi+eax+03h]
    {2} sbb bl,00h
    {0} jz @@DECIDE_NEXT_STEP
    @nx2mtx:
    {1} sub esi,ebp
    {2} add eax,04h
    {0} jnz @zeroincol
    @c2col:
    {0} mov esi,ecx
    {1} add esi,[esp+__MTX]
    {2} sub esi,ebp
    @check2col:
    {0} add esi,04h
    {1} add ecx,04h
    {2} jz @@5TH_STEP
    {0} cmp byte ptr [edi+ecx],00h
    {1} mov eax,ebp
    {2} jnz @check2col
    {0} jmp @zeroincol
    @@5TH_STEP:
    lea ebx,[ebp+03h]
    mov esi,[esp+__MTX]
    @nx5row:
    mov eax,[edi+ebx-03h]
    sub ecx,edx
    xor eax,edx
    cmovs edx,ecx
    mov ecx,ebp
    @decrease_row_free:
    {0} bt dword ptr [edi+ecx],00h
    {1} mov al,[esi+03h]
    {2} adc al,[edi+ebx]
    {0} mov eax,00000000h
    {1} cmovz eax,edx
    {2} sub [esi],eax
    {0} add esi,04h
    {1} add ecx,04h
    {2} jnz @decrease_row_free
    add ebx,04h
    js @nx5row
    mov eax,[esp+__FREE0]
    xor edx,edx
    mov esi,eax
    sub eax,[esp+__MTX]
    idiv ebp
    neg eax
    lea ecx,[ebp+edx]
    lea eax,[ebp+eax*04h]
    @@DECIDE_NEXT_STEP:
    xor edx,edx
    mov [esp+__FREE0],esi
    add edx,[esi]
    jnz @nx2mtx
    mov ebx,eax
    sub eax,ebp
    add edx,[edi+eax*02h+__0STAR]
    jnz @@3RD_STEP
    @@4TH_STEP:
    sub edx,ebp
    jmp @newstar
    @0_star:
    mov [edi+ebx*02h+__0STAR],ecx
    mov ecx,[edi+eax*02h+__COLON]
    @newstar:
    mov ebx,eax
    lea eax,[edx-04h]
    @starincol:
    cmp [edi+eax*02h+__0STAR],ecx
    jz @0_star
    sub eax,04h
    jns @starincol
    mov [edi+ebx*02h+__0STAR],ecx
    @@1ST_STEP:
    sub dword ptr [esp+__SYS0],01h
    mov ebx,edi
    mov ecx,ebp
    jz @count_result_STACK
    mov edx,[edi]
    @restructure:
    {0} mov esi,[ebx+__0STAR]
    {1} mov byte ptr [edi+ecx+03h],00h
    {2} add ebx,08h
    {0} mov byte ptr [edi+esi],01h
    {1} add ecx,04h
    {2} jnz @restructure
    mov [edi],edx
    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:
    {0} mov edx,[edi+ecx*02h+__0STAR]
    {1} add ecx,04h
    {2} add edx,ebp
    {0} add eax,[esi+edx]
    {1} shr edx,02h
    {2} add esi,ebp
    {0} cmp ecx,ebp
    {1} mov [ebx],dl
    {2} lea ebx,[ebx+01h]
    {0} jnz @results

    [ Szerkesztve ]

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #56 üzenetére

    Mindez a gyakorlatban:

    @new:
    mov ecx,00FFFFDFh
    sub esp,DESTINATIONSIZE
    sub ebp,01h
    and ecx,dword ptr [esi+SRC.JOB]
    xor eax,eax
    xor ebx,ebx
    mov [esp+DESTINATION.FIELD1],edi
    mov [esp+DESTINATION.FIELD2],esi
    mov [esp+DESTINATION.FIELD3],eax
    @next: <<<========================================
    mov edx,ecx |
    and cl,0DFh |
    and edx,03h |
    cmp eax,edx |
    rcl eax,01h |
    xor edx,edx |
    neg eax |
    cmp edx,[esp+DESTINATION.FIELD3] |
    rcl edx,01h |
    and eax,edi |
    sub edx,01h |
    and edx,eax |
    xor eax,eax |
    or [esp+DESTINATION.FIELD3],edx |
    sub eax,esi |
    @same: <<<=============================== |
    mov [esi+SRC.FIELD2],bp | |
    mov edx,dword ptr [esi+SRCSIZE+SRC.FIELD1] | |
    add esi,SRCSIZE | |
    and edx,00FFFFDFh | |
    xor edx,ecx | |
    jz @same =================================| |
    or dl,cl | |
    jz @same ================================= |
    add eax,esi |
    mov dl,00h |
    cmp eax,60*x*SRCSIZE |
    rcl cl,01h |
    imul eax,xxx |
    cmp cl,01h |
    rcl dl,01h |
    and cl,(00000011b shl 1) |
    add edi,eax |
    xor eax,eax |
    cmp cl,01h |
    rcl eax,01h |
    mov cl,[esi+SRC.FIELD1] |
    neg eax |
    and ebx,eax |
    not eax |
    and eax,edi |
    or ebx,eax |
    xor eax,eax |
    test edx,edx |
    jz @next =======================================
    mov [esp+DESTINATION.FIELD5],edi
    cmp dword ptr [esi+SRC.FIELD1],-1
    mov [esp+DESTINATION.FIELD4],ebx
    jnz @new

    [ Szerkesztve ]

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #63 üzenetére

    Még pár 10 millió órajelnyi csökkentés benne volt Netburst-ön, a @down ciklus kisebbre vételének (20 » 16 utasítás) köszönhetően.

    Utasításadatok a 2 konkrét gépre immár az AIDA64 Instruction Dump-nak megfelelően (Northwood és Prescott):

    mov eax,[esi-08h+__PRIO] // (1) 2/1 p2 LOAD (1) 4/1 p2 LOAD
    mov ebx,[esi+__PACKADAT2] // (1) 2/1 p2 LOAD (1) 4/1 p2 LOAD
    or edx,-1 // (1) d/d p0 LOGIC (1) 1/d p0 LOGIC
    cmp eax,[esp+__STOPINDEX] // (2) 3/1 p01+2 ALU+LOAD (2) 5/1 p01+2 ALU+LOAD
    mov ebp,[esi+edi*08h+__PRIO] // (1) 2/1 p2 LOAD (1) 4/1 p2 LOAD
    mov ebx,[ebx+eax*04h] // (1) 2/1 p2 LOAD (1) 4/1 p2 LOAD
    jz @finish // (1) 0/4 p0 BRANCH (1) 0/4 p0 BRANCH
    mov [esi+eax*08h+__CONN],eax // (2) 1/2 p0+3 STORE+STA (2) 1/2 p0+3 STORE+STA
    sub edi,edx // (1) d/d p01 ALU (1) 1/d p01 ALU
    jg @finish // (1) 0/4 p0 BRANCH (1) 0/4 p0 BRANCH
    mov [esi+__RELAXED],eax // (1) 1/2 p0 STORE (1) 1/2 p0 STORE
    jz @block // (1) 0/1 p0 BRANCH (1) 0/1 p0 BRANCH
    prefetchnta [ebx] // (6) 6/6 p2 LOAD (1) 1/1 p2 LOAD
    mov ebp,[esi+ebp*08h+__DIST] // (1) 2/1 p2 LOAD (1) 4/1 p2 LOAD
    mov [esi+__HEADER],ebx // (1) 1/2 p0 STORE (1) 1/2 p0 STORE
    @down: //
    lea eax,[edx+edx] // (1) d/d p01 ALU (1) 1/d p01 ALU
    mov ecx,[esi+eax*08h-08h+__PRIO] // (1) 2/1 p2 LOAD (1) 4/1 p2 LOAD
    cmp eax,edi // (1) d/d p01 ALU (1) 1/d p01 ALU
    jl @insertdown // (1) 0/4 p0 BRANCH (1) 0/4 p0 BRANCH
    mov ebx,[esi+eax*08h+00h+__PRIO] // (1) 2/1 p2 LOAD (1) 4/1 p2 LOAD
    mov ecx,[esi+ecx*08h+__DIST] // (1) 2/1 p2 LOAD (1) 4/1 p2 LOAD
    jz @child // (1) 0/4 p0 BRANCH (1) 0/4 p0 BRANCH
    cmp ecx,[esi+ebx*08h+__DIST] // (2) 3/1 p01+2 ALU+LOAD (2) 5/1 p01+2 ALU+LOAD
    sbb eax,00h // (3) 7/7 p1 ALU 1 (3) 10/10 p1 ALU 1
    mov ebx,[esi+eax*08h+__PRIO] // {1) 2/1 p2 LOAD (1) 4/1 p2 LOAD
    @child: //
    cmp ebp,[esi+ebx*08h+__DIST] // (2) 3/1 p01+2 ALU+LOAD (2) 5/1 p01+2 ALU+LOAD
    @insertdown: //
    cmovbe ebx,[esi+edi*08h-08h+__PRIO] // (4) 6/1 p01+2 ALU+LOAD (4) 10/3 p01+2 ALU+LOAD
    mov [esi+edx*08h+__PRIO],ebx // (2) 1/2 p0+3 STORE+STA (2) 1/2 p0+3 STORE+STA
    mov [esi+ebx*08h+__CONN],edx // (2) 1/2 p0+3 STORE+STA (2) 1/2 p0+3 STORE+STA
    mov edx,eax // (1) d/d p01 ALU (1) 1/d p01 ALU
    jnbe @down // (1) 0/4 p0 BRANCH (1) 0/4 p0 BRANCH
    mov ebx,[esi+__HEADER] // (1) 2/1 p2 LOAD (1) 4/1 p2 LOAD
    @block: //
    movzx eax,byte ptr [ebx+STRUCT0.FIELD0] // (1) 2/1 p2 LOAD (1) 4/1 p2 LOAD
    movzx ecx,byte ptr [ebx+STRUCT0.FIELD1] // (1) 2/1 p2 LOAD (1) 4/1 p2 LOAD
    add ebx,STRUCT0SIZE-STRUCT1SIZE // (1) d/d p01 ALU (1) 1/d p01 ALU
    cmp byte ptr [esp+WORKAREA0+eax],00h // (2) 3/1 p01+2 ALU+LOAD (2) 5/1 p01+2 ALU+LOAD
    jz @entry // (1) 0/4 p0 BRANCH (1) 0/4 p0 BRANCH
    mov [esi+__HEADER],ecx // (1) 1/2 p0 STORE (2) 1/2 p0 STORE
    @connects: //
    sub dword ptr [esi+__HEADER],01h // (3) 9/2 p01+2 ALU+LOAD+STORE (3) 5/2 p01+2 ALU+LOAD+STO
    js @entry // (1) 0/4 p0 BRANCH (1) 0/4 p0 BRANCH
    mov ecx,[ebx+STRUCT1SIZE+STRUCT1.FIELD0] // (1) 2/1 p2 LOAD (1) 4/1 p2 LOAD
    add ebx,STRUCT1SIZE // (1) d/d p01 ALU (1) 1/d p01 ALU
    movzx edx,byte ptr [ebx+STRUCT1.FIELD1] // (1) 2/1 p2 LOAD (1) 4/1 p2 LOAD
    cmp dword ptr [esi+ecx*08h+__CONN],00h // (2) 3/1 p01+2 ALU+LOAD (2) 5/1 p01+2 ALU+LOAD
    jg @connects // (1) 0/4 p0 BRANCH (1) 0/4 p0 BRANCH
    @label1: //
    mov al,[ebx+STRUCT1.FIELD2] // (1) 3/1 p2 LOAD (1) 5/1 p2 LOAD
    mov ebp,[ebx+STRUCT1.FIELD3] // (1) 2/1 p2 LOAD (1) 4/1 p2 LOAD
    or al,[ebx+STRUCT1.FIELD4] // (2) 3/1 p0+2 LOGIC+LOAD (2) 5/1 p0+2 LOGIC+LOAD
    and al,[esp+WORKAREA1+edx] // (2) 3/1 p0+2 LOGIC+LOAD (2) 5/1 p0+2 LOGIC+LOAD
    cmp edx,11 // (1) d/d p01 ALU (1) 1/d p01 ALU
    mov edx,10000*1000 // (1) d/d p01 ALU (1) 1/d p01 ALU
    cmovnz edx,ebp // (3) 6/1 p01 ALU (3) 10/d p01 ALU
    add edx,ebp // (1) d/d p01 ALU (1) 1/d p01 ALU
    cmp al,00h // (1) d/d p01 ALU (1) 1/d p01 ALU
    movzx eax,byte ptr [ebx+STRUCT1.FIELD5] // (1) 2/1 p2 LOAD (1) 4/1 p2 LOAD
    cmovnz ebp,edx // (3) 6/1 p01 ALU (3) 10/d p01 ALU
    @label2: //
    cmp al,0FFh // (1) d/d p01 ALU (1) 1/d p01 ALU
    jnz @label4 // (1) 0/4 p0 BRANCH (1) 0/4 p0 BRANCH
    @label3: //
    mov al,[ebx+STRUCT1.FIELD6] // (1) 2/1 p2 LOAD (1) 5/1 p2 LOAD
    lea edx,[ebp+1000*1000] // (1) d/d p01 ALU (1) 1/d p01 ALU
    cmp al,[esp+ARGUMENT1] // (2) 3/1 p01+2 ALU+LOAD (2) 5/1 p01+2 ALU+LOAD
    mov eax,[esi+__RELAXED] // (1) 2/1 p2 LOAD (1) 4/1 p2 LOAD
    cmova edx,ebp // (3) 6/1 p01 ALU (3) 10/d p01 ALU
    sub ebp,ebp // (1) d/d p01 ALU (1) 1/d p01 ALU
    cmp ebp,[esi+ecx*08h+__CONN] // (2) 3/1 p01+2 ALU+LOAD (2) 5/1 p01+2 ALU+LOAD
    rcl ebp,01h // (1) 4/4 p1 ALU 1 (1) 7/7 p1 ALU 1
    sub ebp,01h // (1) d/d p01 ALU (1) 1/d p01 ALU
    add edx,[esi+eax*08h+__DIST] // (2) 3/1 p01+2 ALU+LOAD (2) 5/1 p01+2 ALU+LOAD
    or ebp,edx // (1) d/d p0 LOGIC (1) 1/d p0 LOGIC
    cmp [esi+ecx*08h+__DIST],ebp // (2) 3/1 p01+2 ALU+LOAD (2) 5/1 p01+2 ALU+LOAD
    jle @connects // (1) 0/4 p0 BRANCH (1) 0/4 p0 BRANCH
    mov ebp,[esi+ecx*08h+__CONN] // (1) 2/1 p2 LOAD (1) 4/1 p2 LOAD
    mov [esi+ecx*08h+__DIST],edx // (2) 1/2 p0+3 STORE+STA (2) 1/2 p0+3 STORE+STA
    neg ecx // (1) d/d p0 LOGIC (1) 1/d p0 LOGIC
    cmp ebp,00h // (1) d/d p01 ALU (1) 1/d p01 ALU
    mov [esi+ecx*08h+__PREV],eax // (2) 1/2 p0+3 STORE+STA (2) 1/2 p0+3 STORE+STA
    jnz @moveup // (1) 0/4 p0 BRANCH (1) 0/4 p0 BRANCH
    sub edi,01h // (1) d/d p01 ALU (1) 1/d p01 ALU
    mov ebp,edi // (1) d/d p01 ALU (1) 1/d p01 ALU
    @moveup: //
    mov eax,ebp // (1) d/d p01 ALU (1) 1/d p01 ALU
    sar ebp,01h // (1) 4/1 p1 MMX_SHIFT (1) 1/d p1 SHIFT
    mov ecx,[esi+ebp*08h+__PRIO] // (1) 2/1 p2 LOAD (1) 4/1 p2 LOAD
    cmp eax,-2 // (1) d/d p01 ALU (1) 1/d p01 ALU
    ja @insertup // (1) 0/4 p0 BRANCH (1) 0/4 p0 BRANCH
    cmp edx,[esi+ecx*08h+__DIST] // (2) 3/1 p01+2 ALU+LOAD (2) 5/1 p01+2 ALU+LOAD
    @insertup: //
    cmovae ecx,[ebx+STRUCT1.FIELD0] // (4) 6/1 p01+2 ALU+LOAD (4) 10/3 p01+2 ALU+LOAD
    mov [esi+eax*08h+__PRIO],ecx // (2) 1/2 p0+3 STORE+STA (2) 1/2 p0+3 STORE+STA
    mov [esi+ecx*08h+__CONN],eax // (2) 1/2 p0+3 STORE+STA (2) 1/2 p0+3 STORE+STA
    jnae @moveup // (1) 0/4 p0 BRANCH (1) 0/4 p0 BRANCH
    jmp @connects // (1) 0/1 p0 BRANCH (1) 0/1 p0 BRANCH
    @label4: //
    lea edx,[eax+eax*04h] // (2) 4/1 p01 ALU (2) 2/1 p01 ALU
    add edx,edx // (1) d/d p01 ALU (1) d/d p01 ALU
    sub eax,100 // (1) d/d p01 ALU (1) 1/d p01 ALU
    cmovbe eax,edx // (3) 6/1 p01 ALU (3) 10/3 p01 ALU
    cmp eax,[esp+ARGUMENT1] // (2) 3/1 p01+2 ALU+LOAD (2) 5/1 p01+2 ALU+LOAD
    lea edx,[ebp+1000*1000] // (1) d/d p01 ALU (1) 1/d p01 ALU
    cmovna ebp,edx // (3) 6/1 p01 ALU (3) 10/d p01 ALU
    jmp @label3 // (1) 0/1 p0 BRANCH (1) 0/1 p0 BRANCH

    [ Szerkesztve ]

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #51 üzenetére

    Ennyit jelent 1 év...
    Újra elővettem (most már nem hagyok kritikus kódokat évekre elsüllyedni), kicsit átszerveztem a memóriahasználatot, a @@4TH_STEP-et és az elejét.

    63 db 25x25 mátrix/ezredmásodperc (K10 Opteron @2640 Mhz) így is megvan, jóval kisebb kóddal, IMUL+IDIV nélkül és kevesebb memóriaírással (jobban szereti a Celeron D @2266 Mhz, ő így 13,6 mátrixot számol ki ezredmásodpercenként):

    mov eax,edi
    pushad
    shl ebp,02h
    xor ecx,ecx
    lea edx,[ebp-01h]
    mov eax,edi
    lea edi,[ebx+ebp*02h]
    neg ebp
    @mark0:
    mov [ebx+edx*04h],ecx
    sub edx,01h
    jns @mark0
    @@REDUCE_ROWS:
    mov [edi+00h],edx
    mov ebx,ebp
    @rowmin:
    mov esi,02000000h
    mov ecx,ebp
    xor edx,edx
    @findrowmin:
    cmp esi,[eax]
    cmova esi,[eax]
    cmovz edx,ecx
    add eax,04h
    add ecx,04h
    jnz @findrowmin
    mov ecx,ebp
    cmp esi,02000000h
    jz @specific
    @subrow:
    xor edx,edx
    cmp byte ptr [eax+ecx+__MARKBYTE],00h
    cmovz edx,esi
    sub [eax+ecx],edx
    add ecx,04h
    jnz @subrow
    add ebx,04h
    jnz @rowmin
    jmp @@RECUDE_COLUMNS
    @specific:
    xor [edi+edx*02h+__0STARROW],ebx
    jns @@ABNORMAL_EXIT
    neg ecx
    mov [edi+ebx*02h+__COLROWMARK],edx
    add ecx,ebx
    mov [edi+ecx*02h+__0STAR],edx
    add ebx,04h
    jnz @rowmin
    @@RECUDE_COLUMNS:
    sub ebx,04h
    sub eax,04h
    cmp ebx,ebp
    jl @@1ST_STEP
    cmp dword ptr [edi+ebx*02h+__0STARROW],0
    jnz @@RECUDE_COLUMNS
    mov esi,02000000h
    mov ecx,ebp
    @findcolmin:
    cmp esi,[eax]
    cmova esi,[eax]
    add eax,ebp
    add ecx,04h
    jnz @findcolmin
    lea ecx,[ebp-04h]
    cmp esi,02000000h
    jz @@ABNORMAL_EXIT
    @subcol:
    xor edx,edx
    add ecx,04h
    jz @@RECUDE_COLUMNS
    sub eax,ebp
    cmp dl,[eax+__MARKBYTE]
    cmovz edx,esi
    sub [eax],edx
    jnz @subcol
    mov edx,[edi+ecx*02h+__COLROWMARK]
    or edx,[edi+ebx*02h+__0STARROW]
    mov edx,ecx
    jnz @subcol
    mov [edi+ebx*02h+__0STARROW],edx
    sub edx,ebp
    mov [edi+ecx*02h+__COLROWMARK],ebx
    mov [edi+edx*02h+__0STAR],ebx
    jmp @subcol
    @@ABNORMAL_EXIT:
    add esp,20h
    xor eax,eax
    mov edx,7FFFFFFFh
    stc
    ret

    @@3RD_STEP:
    mov byte ptr [edi+edx*02h+__ROWMARK],0FFh
    mov byte ptr [edi+ebx*02h+__COLMARK],00h
    mov [edi+eax*02h+__COLON],ecx
    @@2ND_STEP:
    lea ecx,[ebp-04h]
    mov edx,00FFFFFFh
    @chk2mtx:
    mov ebx,eax
    sub eax,ebp
    mov esi,[esp+__MTX]
    shl eax,10h
    mov ax,cx
    test ebx,ebx
    cmovns eax,ebx
    mov ebx,ebp
    @check2col:
    add ecx,04h
    jz @@5TH_STEP
    cmp byte ptr [edi+ecx*02h+__COLMARK],00h
    jnz @check2col
    add esi,ecx
    sal ecx,08h
    @zeroincol:
    sub esi,ebp
    mov cl,[edi+ebx*02h+__ROWMARK]
    cmp edx,[esi]
    sbb cl,00h
    cmovz eax,ebx
    cmovz edx,[esi]
    add ebx,04h
    jnz @zeroincol
    sar ecx,08h
    test edx,edx
    jnz @chk2mtx
    mov edx,eax
    sub eax,ebp
    add ebx,[edi+eax*02h+__0STAR]
    jnz @@3RD_STEP
    jmp @@4TH_STEP
    @@5TH_STEP:
    mov [esp+__FREE0],eax
    @nx5row:
    mov eax,edx
    sub ecx,edx
    xor eax,[edi+ebx*02h+__COLROWMARK]
    cmovs edx,ecx
    mov ecx,ebp
    sub esi,ebp
    @decrease_row_free:
    bt dword ptr [edi+ecx*02h+__COLMARK],00h
    mov al,[esi+ecx+__MARKBYTE]
    adc al,[edi+ebx*02h+__ROWMARK]
    mov eax,00000000h
    cmovz eax,edx
    sub [esi+ecx],eax
    add ecx,04h
    jnz @decrease_row_free
    add ebx,04h
    jnz @nx5row
    movzx eax,word ptr [esp+__FREE0+02h]
    movsx ecx,word ptr [esp+__FREE0+00h]
    lea edx,[eax+ebp]
    add ebx,[edi+eax*02h+__0STAR]
    jnz @@3RD_STEP
    @@4TH_STEP:
    mov [edi+eax*02h+__0STAR],ecx
    mov eax,[edi+ecx*02h+__0STARROW]
    mov [edi+ecx*02h+__0STARROW],edx
    mov edx,eax
    sub eax,ebp
    mov ecx,[edi+eax*02h+__COLON]
    test edx,edx
    jnz @@4TH_STEP
    @@1ST_STEP:
    mov edx,ebp
    mov ecx,[esp+__SYS0]
    @restructure:
    mov eax,[edi+edx*02h+__0STARROW]
    shr eax,1Fh
    sub ecx,eax
    mov [edi+edx*02h+__COLROWMARK],eax
    add edx,04h
    jnz @restructure
    test ecx,ecx
    jnz @@2ND_STEP

    @count_result_STACK:
    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 ]

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #72 üzenetére

    A hozzá készített multithread-hívó kód egy szálának részlete, ahogy én látom/írom:

    Az alap algoritmus sajátossága, hogy NxN méretű kiindulási mátrixra lépésenként legalább 2, legfejlebb N/2 új mátrixot generál és számoltat, törekedve arra, hogy minél kisebb legyen ez a szám; így többszálúsítással legalább 2x-esre gyorsul az algoritmus, a 2 magos CPU-kat teljesen kihasználja. (Efelett azonban nem skálázódik a magszámmal: bár 60x60-as mátrix esetén már 30 szálról van szó, 8 magos gépen kb. 40-60%-os tipikus terhelést produkál.)
    Ebből a természetéből kifolyólag célravezetőbb minél kisebb terhelésre optimalizálni a teljes algoritmust, így ha bármi más program is fut mellette, akkor is hozza a legjobb eredményeket.

    A többszálú kód tesztelését ezért először egymagos Prescott Celeron D-n csináltam, hogy kiderüljön, a szinkronizációs overhead mellett mennyit jelent az, hogy minden egyes szál saját munkaterületen (2 Kb) és saját munkamátrixon (NxNx4 byte, 25x25-ös mátrix esetén legrosszabb esetben 12x2.5 Kb) dolgozik, míg az egyszálas a cache-elés miatt célszerűen ugyanarra az egyetlen (2+2.5 KB-os) területre:
    - az eredeti egyszálas algoritmus 18,5 mátrix/ezredmásodperc sebességgel dolgozik
    - a többszálas verzió 16,5 mátrix/millisec-et teljesít

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #74 üzenetére

    Tipikus CPU-terhelés:

    (4 másodperces frissítésű Task Manager XP x64-en, 2 db 4 magos Opteron, 32+1 szál, 50x50-es mátrixok)

    Több dolog is leolvasható róla:
    - szerver magos Windows (jelen esetben Windows Server 2003 kernelű XP x64) nem dobálja a szálakat
    - szerver magos Windows esetén a legtöbbet 'használt' szálak egy foglalaton maradnak (NUMA) ("Az alap algoritmus sajátossága, hogy NxN méretű kiindulási mátrixra lépésenként legalább 2, legfejlebb N/2 új mátrixot generál és számoltat, törekedve arra, hogy minél kisebb legyen ez a szám")
    - a fő szál, ami osztja a kiszámolandó mátrixokat a többi szálnak, a 2. magon fut (nem számol mátrixot, viszont nagy a kernel-terhelése), a mindig meglevő 2 mátrixot az 3. és 4. mag, a 3. mátrixot az 1. mag számolja. 4 vagy több kiszámolandó mátrix ritkábban keletkezik, azok kerülnek át a másik CPU-ra.

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #72 üzenetére

    Minor optimalizáció kifejezetten a többszálú alkalmazáshoz, nagy (50x50 méretnél nagyobb) mátrixokhoz: a bemenő memóriaparaméter-terület lehet különálló és a két kulcsciklusban némi +ILP érhető el.
    0-2% gyorsulás többszálas esetben; lassulás egyetlen szálnál vagy kis mátrix esetén sincs.

    xor ecx,ecx
    lea ebx,[ecx+ebp*04h]
    @mark0:
    {0} mov [edi+ebx+__0STARROW],ecx
    {1} add ebx,10h
    {2} jnz @mark0
    mov ecx,ebp
    @@ARGUMENT:
    {0} movsx esi,byte ptr [edx]
    {1} cmp esi,ebx
    {2} lea esi,[ebp+esi*04h]
    {0} mov [edi+esi*04h+__0STARROW],ecx
    {1} cmovs esi,ebx
    {2} add edx,01h
    {0} mov [edi+ecx*04h+__COLROWMARK],esi
    {1} mov [edi+ecx*04h+__0STAR],esi
    {2} add ecx,04h
    {0} jnz @@ARGUMENT
    lea ebx,[ebp-04h]
    @@REDUCE_ROWS:
    add ebx,04h
    jz @@REDUCE_COLUMNS
    sub eax,ebp
    cmp [edi+ebx*04h+__0STAR],ecx
    jnz @@REDUCE_ROWS
    mov ecx,ebp
    or esi,-1
    @findrowmin:
    {0} mov edx,[eax+ecx]
    {1} or edx,[edi+ecx*04h+__0STARROW]
    {2} cmp esi,edx
    {0} cmova esi,edx
    {1} add ecx,04h
    {2} jnz @findrowmin
    {0} cmp esi,ecx
    {1} js @@ABNORMAL_EXIT
    {2} mov ecx,ebp
    @subrow:
    {0} sub [eax+ecx],esi
    {1} add ecx,04h
    {2} jnz @subrow
    jmp @@REDUCE_ROWS
    @@REDUCE_COLUMNS:
    {0} sub ebx,04h
    {1} sub eax,04h
    {2} cmp ebx,ebp
    {0} jl @@1ST_STEP
    {1} cmp [edi+ebx*04h+__0STARROW],ecx
    {2} jnz @@REDUCE_COLUMNS
    or esi,-1
    @findcolmin:
    {0} sub ecx,04h
    {1} mov edx,[eax]
    {2} or edx,[edi+ecx*04h+__COLROWMARK]
    {0} cmp esi,edx
    {1} cmova esi,edx
    {2} add eax,ebp
    {0} cmp ecx,ebp
    {1} jnz @findcolmin
    xor edx,edx
    sub ecx,04h
    test esi,esi
    js @@ABNORMAL_EXIT
    @subcol:
    {0} add ecx,04h
    {1} jz @@REDUCE_COLUMNS
    {2} sub eax,ebp
    {0} sub [eax],esi
    {1} jnz @subcol
    cmp edx,[edi+ecx*04h+__0STAR]
    jnz @subcol
    mov [edi+ebx*04h+__0STARROW],ecx
    not edx
    mov [edi+ecx*04h+__0STAR],ebx
    jmp @subcol
    @@ABNORMAL_EXIT:
    mov esi,[esp+__MARKS]
    or edx,-1
    jmp dword ptr [esp+_INVALIDRESULT]

    @@3RD_STEP:
    {0} mov byte ptr [edi+eax*04h+__ROWMARK],0FFh
    {1} mov [edi+eax*04h+__COLON],ecx
    {2} mov byte ptr [edi+ebx*04h+__COLMARK],00h
    @@2ND_STEP:
    {0} lea ecx,[ebp-04h]
    {1} mov edx,00FFFFFFh
    @chk2mtx:
    {0} mov ebx,eax
    {1} sub eax,ebp
    {2} mov esi,[esp+__MTX]
    {0} shl eax,10h
    {1} mov ax,cx
    {2} test ebx,ebx
    {0} cmovns eax,ebx
    {1} mov ebx,ebp
    @check2col:
    {0} add ecx,04h
    {1} jz @@5TH_STEP
    {2} cmp byte ptr [edi+ecx*04h+__COLMARK],00h
    {0} jnz @check2col
    {0} push ecx
    {1} add esi,ecx
    {2} neg ebp
    @zeroincol:
    {0} movsx ecx,byte ptr [edi+ebx*04h+__ROWMARK]
    {1} or ecx,[esi+ebp]
    {2} add esi,ebp
    {0} cmp ecx,edx
    {1} cmovb edx,ecx
    {2} cmovb eax,ebx
    {0} add ebx,04h
    {1} jnz @zeroincol
    {0} pop ecx
    {1} neg ebp
    {2} cmp edx,ebx
    {0} jnz @chk2mtx
    {0} add ebx,[edi+eax*04h+__0STAR]
    {1} jnz @@3RD_STEP
    {2} jmp @@4TH_STEP
    @@5TH_STEP:
    push eax
    @nx5row:
    {0} mov eax,[edi+ebx*04h+__COLROWMARK]
    {1} sub ecx,edx
    {2} sub esi,ebp
    {0} xor eax,edx
    {1} cmovs edx,ecx
    {2} mov ecx,ebp
    @decrease_row_free:
    {0} movsx eax,byte ptr [edi+ecx*04h+__COLMARK]
    {1} xor eax,edx
    {2} or eax,[esi+ecx]
    {0} mov eax,00000000h
    {1} cmovns eax,edx
    {2} sub [esi+ecx],eax
    {0} add ecx,04h
    {1} jnz @decrease_row_free
    {0} add ebx,04h
    {1} jnz @nx5row
    pop eax
    movsx ecx,ax
    shr eax,10h
    add eax,ebp
    add ebx,[edi+eax*04h+__0STAR]
    jnz @@3RD_STEP
    @@4TH_STEP:
    {0} mov [edi+eax*04h+__0STAR],ecx
    {1} mov edx,eax
    {2} mov eax,[edi+ecx*04h+__0STARROW]
    {0} cmp eax,ebx
    {1} mov [edi+ecx*04h+__0STARROW],edx
    {2} mov ecx,[edi+eax*04h+__COLON]
    {0} jnz @@4TH_STEP
    @@1ST_STEP:
    {1} mov eax,ebp
    {2} mov edx,[esp+__SYS0]
    @restructure:
    {0} movsx ebx,byte ptr [edi+ebp*04h+__FIXEDROW]
    {1} movzx ecx,byte ptr [edi+ebp*04h+__0STARROW+03h]
    {2} shl ebx,10h
    {0} add dl,cl
    {1} add ecx,ebx
    {2} mov [edi+ebp*04h+__COLROWMARK],ecx
    {0} add ebp,04h
    {1} jnz @restructure
    mov ebp,eax
    test edx,edx
    jnz @@2ND_STEP

    mov ebx,[esp+__SAVE]
    mov esi,[esp+__MARKS]
    @results:
    {0} mov ecx,[edi+eax*04h+__0STAR]
    {1} sub ecx,ebp
    {2} add edx,[ebx+ecx]
    {0} shr ecx,02h
    {1} sub ebx,ebp
    {2} mov [esi],cl
    {0} add esi,01h
    {1} add eax,04h
    {2} jnz @results

    [ Szerkesztve ]

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #39 üzenetére

    Line algoritmus nagy mennyiségű vonalhoz, új megfogalmazásban:

    bemenő paraméterek:
    EAX: X0 coordinate
    EDX: Y0 coordinate
    ECX: X1 coordinate
    EBP: Y1 coordinate
    ESI: BITS array
    EDI: _ADDER array
    MM7: [$0000][$0000][width][ 1] // image width + 1 (UINTs)
    XMM5 [ CHS][ CHS][ CHS][ CHS] // sign change constants
    XMM6: [bttom][right][ top][ left] // image boundaries
    XMM7: [-----][-----][-----][ 1.0]

    cvtsi2ss xmm2,eax
    sub ecx,eax
    sub ebp,edx
    push ebx
    mov eax,ecx
    mov ebx,ecx
    sar eax,1Fh
    cvtsi2ss xmm3,edx
    xor ebx,eax
    mov edx,ebp
    sub ebx,eax
    mov eax,ebp
    sar eax,1Fh
    xor edx,eax
    sub edx,eax
    cmp edx,ebx
    jae @movement
    xchg ebp,ecx
    @movement:
    cvtsi2ss xmm1,ebp
    shufps xmm2,xmm3,01000100b
    test ebp,ebp
    jz @return
    cvtsi2ss xmm0,ecx
    rcpss xmm1,xmm1
    shufps xmm2,xmm2,10001000b
    mulss xmm0,xmm1
    shufps xmm0,xmm7,00000000b
    jns @direction
    neg ebp
    xorps xmm0,xmm5
    @direction:
    cmp edx,ebx
    mov ebx,[edi+_PENWIDTH]
    jae @inlineCOORDINATES
    shufps xmm0,xmm0,11000110b
    @inlineCOORDINATES:
    mov al,[edi+_DRAWCOLOR]
    sub edi,ebx
    shufps xmm0,xmm0,10001000b
    @setpixel:
    cvtps2pi mm0,xmm2
    movaps xmm4,xmm6
    cmpltps xmm6,xmm2
    pshufw mm0,mm0,11111000b
    addps xmm2,xmm0
    movmskps edx,xmm6
    movaps xmm6,xmm4
    pmaddwd mm0,mm7
    cmp edx,03h
    jnz @continueLINE
    movd edx,mm0
    mov ecx,ebx
    @rounds:
    add edx,[edi+ecx]
    add ecx,04h
    mov [esi+edx],al
    js @rounds
    @continueLINE:
    sub ebp,01h
    jge @setpixel
    add edi,ebx
    @return:
    pop ebx

    [ Szerkesztve ]

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #77 üzenetére

    xor ebx,ebx
    mov esi,ebp
    mov eax,edi
    @mark0:
    {0} mov [edi+esi*04h+__0STARROW],ebx
    {1*} add esi,04h
    {2*} jnz @mark0
    mov ecx,ebp
    @@ARGUMENT:
    {0} movsx esi,byte ptr [edx]
    {1} cmp esi,ebx
    {2} lea esi,[ebp+esi*04h]
    {0} mov [edi+esi*04h+__0STARROW],ecx
    {1} cmovs esi,ebx
    {0} mov [edi+ecx*04h+__COLROWMARK],esi
    {2} add edx,01h
    {1} mov [edi+ecx*04h+__0STAR],esi
    {0*} add ecx,04h
    {1*} jnz @@ARGUMENT
    lea ebx,[ebp-04h]
    @@REDUCE_ROWS:
    add ebx,04h
    jz @@REDUCE_COLUMNS
    sub eax,ebp
    cmp [edi+ebx*04h+__0STAR],ecx
    jnz @@REDUCE_ROWS
    mov ecx,ebp
    or esi,-1
    @findrowmin:
    {0} mov edx,[eax+ebp]
    {1} or edx,[edi+ebp*04h+__0STARROW]
    {2} cmp esi,edx
    {0} cmova esi,edx
    {1*} add ebp,04h
    {2*} jnz @findrowmin
    {0*} cmp esi,ebp
    {1*} js @@ABNORMAL_EXIT
    {2} mov ebp,ecx
    @subrow:
    {0} sub [eax+ecx],esi
    {1*} add ecx,04h
    {2*} jnz @subrow
    jmp @@REDUCE_ROWS;
    @@REDUCE_COLUMNS:
    {0} sub ebx,04h
    {1} sub eax,04h
    {2*} cmp ebx,ebp
    {0*} jl @@1ST_STEP
    {1*} cmp [edi+ebx*04h+__0STARROW],ecx
    {2*} jnz @@REDUCE_COLUMNS
    or esi,-1
    @findcolmin:
    {0} mov edx,[eax]
    {1} or edx,[edi+ecx*04h-10h+__COLROWMARK]
    {2} sub ecx,04h
    {0} cmp esi,edx
    {1} cmova esi,edx
    {2} add eax,ebp
    {0*} cmp ecx,ebp
    {1*} jnz @findcolmin
    xor edx,edx
    sub ecx,04h
    test esi,esi
    js @@ABNORMAL_EXIT
    @subcol:
    {0*} add ecx,04h
    {1*} jz @@REDUCE_COLUMNS
    {2} sub eax,ebp
    {0} sub [eax],esi
    {1} jnz @subcol
    cmp edx,[edi+ecx*04h+__0STAR]
    jnz @subcol
    mov [edi+ebx*04h+__0STARROW],ecx
    not edx
    mov [edi+ecx*04h+__0STAR],ebx
    jmp @subcol
    @@ABNORMAL_EXIT:
    mov esi,[esp+__MARKS]
    or edx,-1
    jmp dword ptr [esp+_INVALIDRESULT]

    @@3RD_STEP:
    mov [edi+ebx*04h+__COLON],ecx
    cmp esi,ecx
    mov byte ptr [edi+ebx*04h+__ROWMARK],0FFh
    mov byte ptr [edi+esi*04h+__COLMARK],00h
    cmovl ecx,esi
    or esi,-1
    cmp dx,bx
    cmovz ecx,ebp
    cmovz eax,esi
    @@2ND_STEP:
    sub ecx,04h
    @chk2mtx:
    mov esi,edi
    mov ebx,ebp
    @check2col:
    {0*} add ecx,04h
    {1*} jz @@5TH_STEP
    {2} cmp byte ptr [edi+ecx*04h+__COLMARK],00h
    {0} jnz @check2col
    sub ecx,ebp
    add esi,ecx
    push ecx
    @zeroincol:
    {0} movsx ecx,byte ptr [edi+ebx*04h+__ROWMARK]
    {1} or ecx,[esi]
    {2} jz @zero
    {0} cmp ecx,eax
    {1} cmovb eax,ecx
    {2} cmovb edx,ebx
    {0} sub esi,ebp
    {1*} add ebx,04h
    {2*} jnz @zeroincol
    @zero:
    {0} pop esi
    {1} lea ecx,[esi+ebp]
    {2} shl esi,10h
    {0} cmp edx,00h
    {1} mov si,dx
    {2} cmovs edx,esi
    {0*} cmp ebx,00h
    {1*} jz @chk2mtx
    {2} mov esi,[edi+ebx*04h+__0STAR]
    {0*} cmp esi,00h
    {1*} jnz @@3RD_STEP
    {2} jmp @@4TH_STEP
    @@5TH_STEP:
    push edx
    @nx5row:
    {0} mov edx,[edi+ebx*04h+__COLROWMARK]
    {1} sub ecx,eax
    {2} sub esi,ebp
    {0} xor edx,eax
    {1} cmovs eax,ecx
    {2} mov ecx,ebp
    @decrease_row_free:
    {0} movsx edx,byte ptr [edi+ecx*04h+__COLMARK]
    {1} xor edx,eax
    {0} or edx,[esi+ecx]
    {1} mov edx,00000000h
    {2} cmovns edx,eax
    {0} sub [esi+ecx],edx
    {1*} add ecx,04h
    {2*} jnz @decrease_row_free
    add ebx,04h
    jnz @nx5row
    pop ecx
    movsx ebx,cx
    movsx edx,cx
    shr ecx,10h
    add ecx,ebp
    mov esi,[edi+ebx*04h+__0STAR]
    test esi,esi
    jnz @@3RD_STEP
    @@4TH_STEP:
    mov [edi+ebx*04h+__0STAR],ecx
    mov edx,ebx
    mov ebx,[edi+ecx*04h+__0STARROW]
    cmp ebx,esi
    mov [edi+ecx*04h+__0STARROW],edx
    mov ecx,[edi+ebx*04h+__COLON]
    jnz @@4TH_STEP
    @@1ST_STEP:
    {0} mov eax,ebp
    {1} mov dl,0FFh {cdq ?}
    {2} mov ecx,ebp
    @restructure:
    {0} movsx ebx,byte ptr [edi+ebp*04h+__FIXEDROW]
    {1} mov bx,[edi+ebp*04h+__0STARROW+02h]
    {2} and dl,bl
    {0} mov [edi+ebp*04h+__COLROWMARK],ebx
    {1*} add ebp,04h
    {2*} jnz @restructure
    mov ebp,eax
    cmp dl,00h
    jz @@2ND_STEP

    mov ebx,[esp+__SAVE]
    xor edx,edx
    mov esi,[esp+__MARKS]
    @results:
    mov ecx,[edi+eax*04h+__0STAR]
    sub ebx,ebp
    add edx,[ebx+ecx]
    sub ecx,ebp
    shr ecx,02h
    mov [esi],cl
    add esi,01h
    add eax,04h
    jnz @results

    Kis átszervezés:
    - a paraméterként megkapott EDI pozitív oldalán a mátrix van, negatív oldalán a(z N x N méretű bemeneti mátrix esetén N x 16 byte méretű) munkaterület.
    - a szintén paraméterként EDX-ben megkapott leírás bárhol lehet

    Elsősorban a 4 utasítás/órajel dekódolóképességű CPU-kat vettem figyelembe (Core2 és újabb Intel CPU-k, Bulldozer), de adott órajelen a Sandy/Ivy Brigde-en a leggyorsabb, a K10-es Opteron a 2. a sorban, Core2-őn kb. 15-12% a lemaradás.

    60x60-as mátrixon tesztelve jellemzően 2.4 IPC:
    - az egyszálas algoritmus lefutása K10-en
    - a többszálas algoritmus - egy magra kényszerítve - lefutása K10-en

    A Core2-k ciklusfelismerése nagyon rendben van: "A branch instruction is recognized as having loop behavior if it goes one way n-1 times and then goes the other way one time. A loop counter makes it possible to predict branches with loop behavior perfectly if the period nis no longer than 64." Mivel maximum 60 x 60-as mátrixokról van szó, a branch prediction success rate Core2-n 99.5%; K10 esetében 98.5% körül mozog, sajnos Sandy Bridge-nél is: "There appears to be a two-level predictor with a 32-bit global history buffer and a history pattern table of unknown size. There is no specialized loop predictor."

    Az Intel-eket többé-kevésbé visszahúzza a CMOV és a load-op-store utasítások 'lassú' kezelése: ez elsősorban ezen utasítások lassú dekódolása miatt van (Core2), de a Sandy Bridge esetében igen nagy az előrelépés ezen a téren. (Arra viszont jó lenne fényt deríteni, hogy a Sandy Bridge uop-cache-e hány uop-ot tud a végrehajtó egységekhez juttatni órajelenként: úgy tűnik, a 4 nem igaz, 5 vagy 6 a valóság, észben tartva, hogy a raw dekóder 4+1+1+1 = 7-et tud szolgáltatni).
    In Haswell we trust...

    A futásai idő mostmár 60%-a a @decrease_row_free ciklusban, és immár csak 25%-a a @zeroincol ciklusban megy el; a maradék a többi kód és az (itt nem leírt) adminisztráció.

    A fent leírt jelölés + mátrix memóriaelrendezést alkalmazva egy 60x60-as mátrix 15KB összefüggő memóriaterületet igényel, ez megfelel minden modern CPU-nak.

    Core2 óta minden Intel CPU-ban van LSD/loop-puffer az utasításoknak; K10 esetében nincs. Viszont ez sem helytálló teljesen: "The minimum execution time per iteration for a loop is approximately equal to the number of 32-byte boundaries on K10, or 16-byte boundaries on K8, in the code plus 2 times the number of taken branches and jumps."
    K10-en ha egy rövid ciklus 3-többszöröse (3-6-9) utasításból áll, akkor nincs helye játéknak, bele kell férnie egy 32 byte-os területbe. Viszont úgy veszem észre, hogy ha kevesebb (4, 5, 7, 8) utasításból áll a ciklus, akkor a $10-re alignált utasítások nem okoznak késleltetést, viszont új hármast kezdenek; ezzel a statikus 3-as utasításleosztást lehet befolyásolni (lásd @decrease_row_free ciklust: egyetlen 32 byte-os egységbe rendezve lassabb a 8 utasítás lefolyása, mintha az első utasítás $3A-ra - azaz a 3. utasítás $40-re, ezzel indul a következő triplet - van rendezve, így a 3 integer-pipe más utasításokat kap meg, amelyek nem akadályozzák egymást).
    Az utasítások/ciklusok rendezésének (alignálásának) hiánya vagy figyelmen kívül hagyása 15-20% visszaesést jelent a K10-es teljesítményben.

    [ Szerkesztve ]

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #80 üzenetére

    Egy év eltelt, kissé változott a kódolás, de még fontosabb, hogy elkészült a hozzá tartozó egy szálas kiszolgáló kód - amely előkészíti a kiszámolandó mátrixokat - végleges(?) 32 bites változata. Ennek teljes kidolgozása +8-9% sebességnövekedést okozott K10-en.

    jmp @@NEXTMATRIX
    @terminate:
    { x1 } nop
    jmp @@READY
    @@NEXTMATRIX:
    {align $34} nop; mov eax,[APPLICATION]; call TAPPLICATION.PROCESSMESSAGES
    {align $40} mov [ebx+TTSP30.COLLECTOR],edi
    or ecx,-1
    mov eax,[ebx+TTSP30.MEMORY]
    test cl,[ebx+TTSP30.CIRCLESTOP]
    jnz @terminate
    add [ebx+TTSP30.GLOBALSIZE],eax
    {align $50} mov [ebx+TTSP30.MEMORY],ecx
    mov edx,esi
    mov ebp,[esi+TCIRCLE.NEXT]
    cmovc edx,ebp
    mov eax,[edi+TCIRCLE.NEXT]
    cmovc ebp,eax
    {align $5F} mov [ebx+TTSP30.ENTRY],edx
    {align $62} cmovc eax,esi
    mov [esi+TCIRCLE.NEXT],ebp
    mov [edi+TCIRCLE.NEXT],eax
    lea esi,[ebx+TTSP30.RESULTS]
    cmp edx,ebp
    jz @terminate
    {align $70} mov ebx,[edx+TCIRCLE.QUANTITY]
    add dword ptr [edx+TCIRCLE.QUANTITY],02h
    mov ebp,[esp+_ROWSIZE4]
    mov edi,[esp+_CMTX]
    shr ebx,03h
    @createBASE:
    {align $81} mov eax,[edx+ebx*08h+04h]
    mov [esp+_BASEELEMENT+ebx*08h+04h],eax
    mov eax,[edx+ebx*08h+00h]
    mov [esp+_BASEELEMENT+ebx*08h+00h],eax
    {align $90} dec ebx
    jnz @createBASE
    {align $93} add edx,offset(TCIRCLE.SUGGESTED)
    movzx eax,al
    mov [esp+_BASEELEMENT+TCIRCLE.NEXT],edx
    cmp [edx+eax],bl
    {align $A0} jl @matrix0
    mov [esp+_CDEST],ebx
    @INVALIDmatrix:
    {align $A6} mov dword ptr [esi+TRESULT.OPTIMUM],0FFFFFFFFh
    inc ebx
    mov ecx,eax
    @create_matrixes:
    {align $B0} movzx eax,byte ptr [esp+_BASEELEMENT+TCIRCLE.SHORTEST+ebx+00h]
    cmp al,byte ptr [edx-TCIRCLE.SUGGESTED+TCIRCLE.SHORTEST+00h]
    jz @@CHECKRESULTS
    mov [edx+ecx],al
    add esi,TRESULTSIZE
    {align $C0} cmp byte ptr [edx+eax],0FFh
    jnz @INVALIDmatrix
    @matrix0:
    movzx ebx,byte ptr [esp+_BASEELEMENT+TCIRCLE.SHORTEST+ebx+01h]
    mov ecx,[esp+_SIZE2BYTE]
    imul eax,ebp
    shl ebx,02h
    mov [esp+_CDEST],esi
    sub ebx,eax
    mov eax,[esp+_SAVEMTX]
    mov [esi+TRESULT.NXTILTED],ebx
    @copyMTX:
    {align $E2} mov esi,[eax+ecx+04h]
    mov [edi+ecx+04h],esi
    mov esi,[eax+ecx]
    mov [edi+ecx],esi
    {align $F0} sub ecx,08h
    jns @copyMTX
    {align $F5} lea ecx,[esp+_BASEELEMENT+TCIRCLE.TILTEDS]
    mov eax,[esp+_COUNT386]
    @tilt:
    {align $00} mov [edi+ebx],ebp
    movzx ebx,word ptr [ecx]
    add ecx,02h
    test ebx,ebx
    jnz @tilt
    jmp eax
    { x1 } nop
    @VALIDmatrix:
    {align $10} mov ebx,[esi+TRESULTSIZE+TRESULT.IVALUE]
    mov [esi+TRESULT.OPTIMUM],edx
    mov [esi+TRESULT.CCIRCLE],ecx
    mov edx,[esp+_BASEELEMENT+TCIRCLE.NEXT]
    {align $20} movzx ecx,byte ptr [esp+_BASEELEMENT+TCIRCLE.SHORTEST+ebx-01h]
    jmp @create_matrixes
    { x2 } nop; nop
    @@CHECKRESULTS:
    {align $29} add [CIRCLEVAR],ebx
    mov ebx,offset(TSP30)
    mov ebp,offset(TSP30.RESULTS)
    mov edi,[ebx+TTSP30.COLLECTOR]
    @@AFTERCIRCLE:
    mov eax,[esp+_BASEELEMENT+TCIRCLE.QUANTITY]
    { x1 } nop
    @@HEADMATRIX:
    {align $40} mov esi,[ebx+TTSP30.ENTRY]
    @next:
    cmp ebp,[esp+_CDEST]
    ja @@NEXTMATRIX
    mov ecx,[ebp+TRESULT.OPTIMUM]
    {align $50} add ebp,TRESULTSIZE
    { x1 } nop
    cmp ecx,[ebx+TTSP30.GLOBALOPTIMUM]
    jae @next
    mov edx,[ebp-TRESULTSIZE+TRESULT.CCIRCLE]
    cmp edx,[esp+_MTXSIZE]
    {align @60} jz @@CIRCLE0
    { x1 } nop
    cmp dword ptr [edi+TCIRCLE.NEXT],00h
    jz @@PLUSMEM
    @enqueue:
    add dword ptr [ebx+TTSP30.MEMORY],01h
    {align $70} cmovnz esi,[edi+TCIRCLE.NEXT]
    { x1 } nop
    cmovnz edi,esi
    mov [esi+TCIRCLE.RESULT],ecx
    movzx ecx,dl
    shr edx,08h
    {align $80} lea ebx,[esi+TCIRCLE.SHORTEST+ecx]
    neg ecx
    mov [ebx],dl
    @shortest:
    mov [ebx+ecx],dl
    movzx edx,byte ptr [ebp-TRESULTSIZE+TRESULT.ORDERSET+edx]
    {align $90} add ecx,01h
    jnz @shortest
    movzx edx,byte ptr [esp+_BASEELEMENT+TCIRCLE.SHORTEST+00h]
    lea ebx,[eax-TCIRCLE.QUANTITY]
    shr ebx,03h
    @clone:
    {align $A0} mov eax,[esp+_BASEELEMENT+ebx*08h+04h+TCIRCLE.QUANTITY]
    mov [esi+ebx*08h+04h+TCIRCLE.QUANTITY],eax
    mov eax,[esp+_BASEELEMENT+ebx*08h+00h+TCIRCLE.QUANTITY]
    mov [esi+ebx*08h+00h+TCIRCLE.QUANTITY],eax
    {align $B0} dec ebx
    jns @clone
    mov ebx,[ebp-TRESULTSIZE+TRESULT.NXTILTED]
    mov [esi+eax-02h],ebx
    lea ebx,[TSP30]
    @suggest:
    {align $C0} cmp ecx,[ebp-TRESULTSIZE+TRESULT.IVALUE]
    jae @@HEADMATRIX
    movzx ebx,byte ptr [esp+_BASEELEMENT+TCIRCLE.SHORTEST+ecx+01h]
    add ecx,01h
    mov byte ptr [esi+TCIRCLE.SUGGESTED+edx],bl
    mov edx,ebx
    mov ebx,offset(TSP30)
    jmp @suggest
    {align $DE} { x3 } nop; nop; nop
    { x8 } nop; nop; nop; nop; nop; nop; nop; nop
    @@PLUSMEM:
    {align $E9} lea eax,[ebx+TTSP30.WORKAREAS]; xor edx,edx; call _ADDINT
    mov edx,[ebx+TTSP30.STRUCTURESIZE]; mov ecx,3000; call _REALLO
    {align $00} add [ebx+TTSP30.COLLECTED],ecx
    dec ecx
    @setmem:
    {align $04} mov [eax+edx+TCIRCLE.NEXT],eax
    add eax,edx
    sub ecx,01h
    jnz @setmem
    {align $0E} mov edx,[ebp-TRESULTSIZE+TRESULT.CCIRCLE]
    mov ecx,[ebp-TRESULTSIZE+TRESULT.OPTIMUM]
    mov [edi+TCIRCLE.NEXT],eax
    mov eax,[esp+_BASEELEMENT+TCIRCLE.QUANTITY]
    jmp @enqueue
    { x1 } nop
    @@CIRCLE0:
    ...

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #39 üzenetére

    SSE1 line algoritmus azonos stílusú vonalak láncolt listájára, a #39-hez képest megtáltosítva; align/cím- és Northwood + Merom + K10 portelemzéssel.

    Intel processzorokon Core2 óta a MOVD reg,mmreg (2 órajel) gyorsabb, mint az L1D-olvasás (3-4 órajeé), a Sandy Bridge óra pedig kvázi +regiszterkészletként használhatóak az MMX és XMM regiszterek (1 órajel a MOVD oda-vissza). K10-en sem lassabb a MOVD reg,mmreg, mint az L1D-hozzáférés.

    {@31} lea edi,[esi+TBITMAPFILE.IDATA+_ADDER] // p01 d (1) alu p0 1 (1) p012 1 (1) ALU
    xorps xmm1,xmm1 // p1 2 (1) mmxalu p015 1 (1) p34 2 (1) FA/M
    mov eax,[esi+TBITMAPFILE.IDATA+_DX] // p2 2 (1) load p2 2 (1) p012 3 (1) MEM
    {@40} cvtpi2ps xmm3,[edi-_ADDER+_TOPLEFT0] // p1+2 10 (4) mmx+load p1+2 (1) p34+5 7 (2) FPU+MEM
    pcmpeqd xmm4,xmm4 // p1 2 (1) mmxalu p01 1 (1) p34 2 (1) FA/M
    cvtpi2ps xmm2,[edi-_ADDER+_RIGHT] // p1+2 10 (4) mmx+load p1+2 (1) p34+5 7 (2) FPU+MEM
    pcmpeqd xmm7,xmm7 // p1 2 (1) mmxalu p01 1 (1) p34 2 (1) FA/M
    {@50} mov ecx,[edi-_ADDER+_PEN] // p2 2 (1) load p2 2 (1) p012 3 (1) MEM
    pslld xmm4,25 // p1 2 (1) mmxshf p0 1 (1) p34 3 (1) FA/M
    mov esi,[esi+TBITMAPFILE.BITS] // p2 2 (1) load p2 2 (1) p012 3 (1) MEM
    pslld xmm7,1Fh // p1 2 (1) mmxshf p0 1 (1) p34 3 (1) FA/M
    {@60} movd mm2,[edi-_ADDER+_COLOR] // p2 8 (1) mmxalu p2 2 (1) p345 4 (1) FANY
    shl eax,10h // p1 4 (1) mmxshf p05 1 (1) p012 1 (1) ALU
    movlhps xmm3,xmm2 // p1 2 (1) mmxshf p0 1 (1) p34 3 (1) FA/M
    add eax,01h // p01 d (1) alu p015 1 (1) p012 1 (1) ALU
    sub edi,ecx // p01 d (1) alu p015 1 (1) p012 1 (1) ALU
    {@6F} psrld xmm4,02h // p1 2 (1) mmxshf p0 1 (1) p34 3 (1) FA/M
    movd mm0,eax // p1 2 (2) mmxalu p05 2 (1) p012 6 (2) ALU
    jmp @1stline // p1 0 (1) branch p5 1 (1) p012 2 (1) ALU
    { x7 } mov eax,00000000h; mov edx,ecx //
    @reorder: //
    {@80} shufps xmm0,xmm0,11011000b // p1 4 (1) mmxshf p1 3 (3) p34 3 (1) FA/M
    @setpixels: //
    {@84} cvtps2pi mm1,xmm5 // p0+1 7 (3) fp-mmx p1 3 (1) p5 4 (1) FMISC
    movaps xmm2,xmm3 // p0 6 (1) mov p015 1 (1) p345 2 (1) FANY
    mov ebx,ecx // p01 d (1) alu p015 1 (1) p012 1 (1) ALU
    pshufw mm1,mm1,11011000b // p1 2 (1) mmxshf p5 1 (1) p34 2 (1) FA/M
    {@90} cmpltps xmm2,xmm5 // p1 4 (1) fpadd p1 3 (1) p3 (1) FADD
    addps xmm5,xmm0 // p1 4 (1) fpadd p1 3 (1) p3 4 (1) FADD
    pmaddwd mm1,mm0 // p1 6 (1) fpmul p1 3 (1) p4 3 (1) FMUL
    movmskps edx,xmm2 // p1 6 (2) fp p0 1 (1) p34 3 (1) FA/M
    cmp edx,03h // p01 d (1) alu p015 1 (1) p012 1 (1) ALU
    {@A0} jnz @continueLINE // p0 2 (1) alu p5 1 (1) p012 1 (1) ALU
    movd edx,mm1 // p0 5 (2) fp p015 2 (1) p3 3 (1) FADD
    @round: //
    add edx,[edi+ebx] // p01+2 d+2(2) alu+load p015+2 (1) p012 4 (1) ALU+MEM
    mov [esi+edx],al // p0+3 2 (3) store p 34 3 (1) p012 3 (1) MEM
    add ebx,04h // p01 d (1) alu p015 1 (1) p012 1 (1) ALU
    js @round // p0 0 (1) branch p5 1 (1) p012 1 (1) ALU
    @continueLINE: //
    {@B0} sub ebp,01h // p01 d (1) alu p015 1 (1) p012 1 (1) ALU
    jge @setpixel // p0 0 (1) branch p5 1 (1) p012 1 (1) ALU
    @nxline: //
    {@B5} movd ebx,mm3 // p0 5 (2) fp p015 2 (1) p3 3 (1) FADD
    @1stline: //
    {@B8} cmp ebx,00h // p01 d (1) alu p015 1 (1) p012 1 (1) ALU
    jz @return // p0 0 (1) branch p5 1 (1) p012 1 (1) ALU
    mov eax,[ebx+TMAPRECORD.REF] // p2 2 (1) load p2 2 (1) p012 3 (1) MEM
    {@C0} mov edx,[ebx+TMAPRECORD.SELF] // p2 2 (1) load p2 2 (1) p012 3 (1) MEM
    mov ebp,[eax+TMAPHEADER.YCOOR] // p2 2 (1) load p2 2 (1) p012 3 (1) MEM
    cvtpi2ps xmm5,[edx+TMAPHEADER.XCOOR] // p1+2 10+2(4) mmx+load p1+2 (1) p34+5 7 (2) FPU+MEM
    mov eax,[eax+TMAPHEADER.XCOOR] // p2 2 (1) load p2 2 (1) p012 3 (1) MEM
    sub ebp,[edx+TMAPHEADER.YCOOR] // p01+2 d+2(2) alu+load p015+2 (1) p012 4 (1) ALU+MEM
    sub eax,[edx+TMAPHEADER.XCOOR] // p01+2 d+2(2) alu+load p015+2 (1) p012 4 (1) ALU+MEM
    {@D0} xor edx,edx // p0 d (1) logic p015 1 (1) p012 1 (1) ALU
    movlhps xmm5,xmm5 // p1 2 (1) mmxshf p0 1 (1) p34 3 (1) FA/M
    movd mm3,ds:[ebx+TMAPRECORD.NX] // p2 8 (1) mmxalu p2 2 (1) p345 4 (1) FANY
    xor ebx,ebx // p0 d (1) logic p015 1 (1) p012 1 (1) ALU
    sub edx,ebp // p01 d (1) alu p015 1 (1) p012 1 (1) ALU
    cmovs edx,ebp // p0+1 6 (3) alu p015 2 (2) p012 1 (1) ALU
    {@E0} sub ebx,eax // p01 d (1) alu p015 1 (1) p012 1 (1) ALU
    cmovs ebx,eax // p0+1 6 (3) alu p015 2 (2) p012 1 (1) ALU
    cmp edx,ebx // p01 d (1) alu p015 1 (1) p012 1 (1) ALU
    mov ebx,ebp // p01 d (1) alu p015 1 (1) p012 1 (1) ALU
    cmovb ebx,eax // p0+1 6 (3) alu p015 2 (2) p012 1 (1) ALU
    cmovb eax,ebp // p0+1 6 (3) alu p015 2 (2) p012 1 (1) ALU
    cmovb ebp,ebx // p0+1 6 (3) alu p015 2 (2) p012 1 (1) ALU
    {@F2} sbb edx,edx // p1 5 (3) alu p015 2 (2) p012 1 (1) ALU
    neg ebx // p0 d (1) alu0 p015 1 (1) p012 1 (1) ALU
    mov ecx,ecx //
    cvtsi2ss xmm0,eax // p1 10 (3) fp-mmx p1 4 (1) p345 14 (v) FPU+ALU
    cvtsi2ss xmm1,ebp // p1 10 (3) fp-mmx p1 4 (1) p345 14 (v) FPU+ALU
    {@00} movaps xmm2,xmm1 // p0 6 (1) mov p015 1 (1) p345 2 (1) FANY
    divss xmm0,xmm1 // p1 23 (1) fpdiv p0 17 (1) p4 16 (1) FMUL
    cmovns ebp,ebx // p0+1 6 (3) alu p015 2 (2) p012 1 (1) ALU
    shufps xmm2,xmm2,00000000b // p1 4 (1) mmxshf p1 3 (3) p34 3 (1) FA/M
    test edx,edx // p0 d (1) logic p015 1 (1) p012 1 (1) ALU
    {@10} andps xmm2,xmm7 // p1 2 (1) mmxalu p015 1 (1) p34 2 (1) FA/M
    shufps xmm0,xmm4,00000000b // p1 4 (1) mmxshf p1 3 (3) p34 3 (1) FA/M
    movd eax,mm2 // p0 5 (2) fp p015 2 (1) p3 3 (1) FADD
    xorps xmm0,xmm2 // p1 2 (1) mmxalu p015 1 (1) p34 2 (1) FA/M
    {@1D} jz @reorder // p0 0 (1) branch p5 1 (1) p012 2 (1) ALU
    {@23} shufps xmm0,xmm0,01110010b // p1 4 (1) mmxshf p1 3 (3) p34 3 (1) FA/M
    jmp @setpixels // p1 0 (1) branch p5 1 (1) p012 2 (1) ALU
    @return:
    popad
    emms

    [ Szerkesztve ]

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #84 üzenetére

    A vonalakhoz tartozó koordináták kiszámolása (a gráf sajátosságai szerint) és a látható pontok összegyűjtése:

    push eax
    or ebp,-1
    mov edx,00000001h
    xorps xmm2,xmm2
    {@4F} mov ebx,[source]
    cvtsi2ss xmm1,edx
    movlps xmm2,[eax+TMAP.NX]
    xorps xmm3,xmm3
    {@60} mov esi,[destination]
    divss xmm1,[eax+TMAP.ZOOM]
    xorps xmm0,xmm0
    mov edi,[ebx+04h]
    {@70} cvtpi2ps xmm3,[eax+TMAP.BITMAP+TBITMAPFILE.XSIZE]
    shufps xmm1,xmm1,10100000b
    jmp @storecoor
    { x6 } add eax,00h; add edx,00h
    { x1 } nop
    @SSEcoor:
    {@81}{0}movlps xmm0,[edi+HEADER.X]
    {1}movzx eax,byte ptr [edi+HEADER.FIELD0]
    {2}movaps xmm5,xmm1
    {0}movzx ebx,word ptr [edi+HEADER.SIZE]
    {@90}{1}mulps xmm5,xmm0
    {2}movaps xmm4,xmm3
    {0}subps xmm5,xmm2
    {1}add eax,eax
    {2}sub ebx,01h
    {0}movlhps xmm4,xmm5
    {@A1}{1}movsx ebp,al
    {2}or ebp,ebx
    {0}cvtps2pi mm0,xmm5
    {1}sar ebp,1Fh
    {2}cmp byte ptr [edi+HEADER.FIELD1],01h
    {@B0}{0}subps xmm4,xmm5
    {1}mov [esi],edi
    {2}movmskps edx,xmm4
    {0}sbb ebp,edx
    {1}movq [edi+HEADER.XCOOR],mm0
    {2}sar ebp,1Fh
    {@C0}{0}rcr al,01h
    {1}mov [edi+HEADER.FIELD0],al
    {2}lea edi,[edi+ebx+HEADERSIZE+01h]
    @storecoor:
    {0}lea esi,[esi+ebp*04h+04h]
    {1}sub ecx,01h
    {@D0}{2}jnle @SSEcoor
    pop eax
    xor ecx,ecx
    emms
    mov [esi],ecx

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #83 üzenetére

    A gulács megszá'tta a lélkömet, oszt' ezör fontosabb dolgom volt eddig, mint hajlítani ezen a programon.

    De "új év, új szemlélet", hülyébbek meg nem lettünk, szóval ugyan kisebb IPC, de okosabb megközelítés.

    Van benne egy csomó NOP is, az arra fogékonyak kedvéért.

    Sebességnövekedés:
    Pentium 4: +6%
    K10: +20,5%
    Core2 +32,4%

    xor ebx,ebx
    mov esi,ebp
    mov ecx,ebp
    and esi,-8
    add esp,ebp
    mov eax,edi
    {@F1} @mark0:
    {0} mov [edi+esi*04h+00h+__0STARROW],ebx
    {1} mov [edi+esi*04h+10h+__0STARROW],ebx
    {2*} add esi,08h
    {0*} jnz @mark0
    { x2 } nop; nop
    @@ARGUMENT:
    {@00} movsx esi,byte ptr [edx]
    {1} cmp esi,ebx
    {2} lea esi,[ebp+esi*04h]
    {0} mov [edi+esi*04h+__0STARROW],ecx
    {1} cmovs esi,ebx
    {@10} mov [edi+ecx*04h+__COLROWMARK],esi
    {0} inc edx
    {1} mov [edi+ecx*04h+__0STAR],esi
    {2*} add ecx,04h
    {0*} jnz @@ARGUMENT
    { x1 } nop
    mov edx,ebp
    {@20} jmp @freerow
    { x3 } add eax,00h
    {@25} @subrow:
    {0} sub [eax+ecx],esi
    {1*} add ecx,04h
    {2*} jnz @subrow
    { x3 } add ebx,00h
    @@REDUCE_ROWS:
    {0*} add edx,04h
    {1*} jz @@REDUCE_COLUMNS
    @freerow:
    {2} sub eax,ebp
    {0**} cmp [edi+edx*04h+__0STAR],ecx
    {1**} jnz @@REDUCE_ROWS
    {2} or esi,-1
    {@40-} mov ecx,ebp
    @findrowmin:
    {@42} mov ebx,[eax+ebp]
    {1} or ebx,[edi+ebp*04h+__0STARROW]
    {2} cmp esi,ebx
    {0} cmova esi,ebx
    {1*} add ebp,04h
    {2*} jnz @findrowmin
    {0-} mov ebp,ecx
    {1**} cmp esi,00h
    {2**} jns @subrow
    @@ABNORMAL_EXIT:
    {@5A} sub esp,ebp
    mov esi,[esp+__MARKS]
    or edx,-1
    {@60} mov [esi+TRESULT.OPTIMUM],edx
    mov ebx,[esi+TRESULT.NEXTIVALUE]
    jmp dword ptr [esp+_INVALIDRESULT]
    { x3 } add ebp,00h
    @@REDUCE_COLUMNS:
    {0} sub edx,04h
    {1} sub eax,04h
    {2**} cmp edx,ebp
    {0**} jb @@1ST_STEP
    {1**} cmp [edi+edx*04h+__0STARROW],ecx
    {2**} jnz @@REDUCE_COLUMNS
    {@80-} mov esi,ebp
    {@82} @findcolmin:
    {0} mov ebx,[eax]
    {1} or ebx,[edi+ecx*04h-10h+__COLROWMARK]
    {2} sub ecx,04h
    {0} cmp esi,ebx
    {1} cmova esi,ebx
    {@90} add eax,ebp
    {0**} cmp ecx,ebp
    {1**} jnz @findcolmin
    {0-} xor ebx,ebx
    {1} sub ecx,04h
    {2**} cmp esi,00h
    {0**} js @@ABNORMAL_EXIT
    {@A0} @subcol:
    {0*} add ecx,04h
    {1*} jz @@REDUCE_COLUMNS
    {2} sub eax,ebp
    {0} sub [eax],esi
    {1} jnz @subcol
    {0**} cmp ebx,[edi+ecx*04h+__0STAR]
    {@AF**} jnz @subcol
    {@B1} mov [edi+edx*04h+__0STARROW],ecx
    not ebx
    mov [edi+ecx*04h+__0STAR],edx
    jmp @subcol


    @@3RD_STEP:
    {@C0} mov [edi+ebx*04h+__COLON],ecx
    @re2start:
    {@C4-} mov edx,ebp
    lea ecx,[ebp-04h]
    @mark2row:
    {@C9} mov byte ptr [edi+ebx*04h+__ROWMARK],0FFh
    {?-} xor ebx,ebx
    mov [edi+esi*04h+__COLMARK],bl
    @@2ND_STEP:
    {@D3} add ecx,04h
    {1*} jz @@5TH_STEP
    {2**} test [edi+ecx*04h+__COLROWMARK],ebp
    {0**} js @@2ND_STEP
    push ecx
    mov ebx,ebp
    {@E0} sub ecx,ebp
    {@E2} @zeroincol:
    {0} movsx esi,byte ptr [edi+ebx*04h+__ROWMARK]
    {1} or esi,[edi+ecx]
    {2} jz @zero
    {0} cmp esi,edx
    {1} cmovb edx,esi
    {@F0} cmovb eax,ebx { >= EBP }
    {0} sub ecx,ebp
    {1*} add ebx,04h
    {2*} jnz @zeroincol
    {@FA} @zero:
    {0} pop esi
    {1-} mov ecx,esi
    {2} shl esi,10h
    {@00} cmp eax,ebp
    {1} mov si,ax { ESI < EBP }
    {2} cmovge eax,esi
    {0**} test ebx,ebx
    {1**} jz @@2ND_STEP
    {2} mov esi,[edi+ebx*04h+__0STAR]
    {@10**} test esi,esi
    {1**} jz @@4TH_STEP
    {2} cmp esi,ecx
    {0} mov [edi+ebx*04h+__COLON],ecx
    {1} cmovl ecx,esi
    {2**} cmp ax,bx
    {@20**} jz @re2start
    {1} sub ecx,04h
    {2} jmp @mark2row
    @@5TH_STEP:
    {0} mov [edi+00h*04h+__COLROWMARK],eax { matrix[0,
    {1-} mov esi,ebp
    {2F} @markedrows:
    {0} sub ecx,ebp
    {@31} movsx eax,byte ptr [edi+esi*04h+__ROWMARK]
    {2} mov [esp+ebx*04h+04h],ecx
    {0} sub ebx,eax
    {1*} add esi,04h
    {2*} jnz @markedrows
    {@40} mov [esp+00h],ebx
    {1} lea esi,[edi+ebp-04h]
    {2} jmp @chk5col
    @increase:
    {@49-} xor ecx,ecx
    {1} test [esi+ebx],ebp
    {2} cmovns ecx,edx
    {0} add [esi+ebx],ecx
    {1} mov ebx,[esp+eax*04h]
    @increase_marked_col:
    {2*} sub eax,01h
    {0*} jns @increase
    {1-2} { x4 } xor eax,eax; xor ecx,ecx
    @chk5col:
    {@60} sub esi,edi
    {1-} mov eax,ebx
    {2} mov ecx,[edi+esi*04h+04h*04h+__COLROWMARK]
    {0} mov ebx,[esp+ebx*04h]
    {1*} add esi,04h
    {2*} jz @zero5item
    {@70} add esi,edi
    {1} sar ecx,1Fh
    {2} js @increase_marked_col
    @decrease_free_col: { IPC: 2.6 }
    {@77} sub ecx,ebp
    {1} { x5 } mov eax,00000000h
    {2-} mov ebx,ebp
    @decrease:
    {@80} movsx eax,byte ptr [edi+ebx*04h+__ROWMARK]
    {1} or eax,[esi+ecx]
    {2} mov eax,00000000h
    {0} cmovns eax,edx
    {1} sub [esi+ecx],eax
    {2} sub ecx,ebp
    {0*} add ebx,04h
    {1*} jnz @decrease
    {0} mov ebx,[esp+00h]
    {1} jmp @chk5col
    @zero5item:
    {@9E} mov edx,ebp
    {@A0} movsx ebx,cx
    sar ecx,10h
    add esi,[edi+ebx*04h+__0STAR]
    jnz @@3RD_STEP
    @@4TH_STEP:
    {0} mov [edi+ebx*04h+__0STAR],ecx
    {1-} mov edx,ebx
    {2} mov ebx,[edi+ecx*04h+__0STARROW]
    {0} mov [edi+ecx*04h+__0STARROW],edx
    {1} mov ecx,[edi+ebx*04h+__COLON]
    {2**} test ebx,ebx
    {0**} jnz @@4TH_STEP
    @@1ST_STEP:
    {@86-} mov ebx,ebp
    @restructure:
    {@88} mov esi,[edi+ebx*04h+__0STARROW]
    {1} and edx,esi
    {2} movsx si,byte ptr [edi+ebx*04h+__FIXEDROW]
    {0} mov [edi+ebx*04h+__COLROWMARK],esi
    {1*} add ebx,04h
    {2*} jnz @restructure
    xor edx,ebp
    {9E} lea ecx,[ebp-04h]
    js @@2ND_STEP


    xor edx,edx
    sub esp,ebp
    mov ecx,ebp
    mov ebx,[esp+__SAVE]
    mov esi,[esp+__MARKS]
    @@results:
    {@B5} mov eax,[edi+ecx*04h+__0STAR]
    {1} sub ebx,ebp
    {2} add edx,[ebx+eax]
    {0} sub eax,ebp
    {@C0} shr eax,02h
    {2} mov [esi],al
    {1} add esi,01h
    {2*} add ecx,04h
    {0*} jnz @@results

    [ Szerkesztve ]

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #88 üzenetére

    .

    [ Szerkesztve ]

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #93 üzenetére

    Kaveri (3.8 GHz): 60 sec alatt 448000 mátrix

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #95 üzenetére

    Simitgatva:

    K10 (2.9 GHz): 53 sec alatt oldja meg a teljes feladatot
    Ivy Bridge (3.8 GHz): 45 sec alatt végez a teljes feladattal
    Core2 (2.5 GHz): 60 sec alatt 479000 mátrix
    P4 Northwood (2.4 GHz): 60 sec alatt 221000 mátrix

    Core-családhoz kis adalék:

    PerfMonitor Record file
    Counter 0 : Non-halted clock cycles
    Counter 1 : Instructions per cycle (IPC)
    Counter 2 : Retired fused uops
    Counter 3 : Retired non-fused uops

    T(ms) c0(M/s) c1(i/c) c2(M/s) c3(M/s)
    50 2500.0 2.2 1323.7 4871.0
    100 2500.0 2.1 1312.8 4842.1
    150 2500.0 2.1 1312.8 4843.9
    200 2500.0 2.1 1305.8 4808.1
    250 2500.0 2.2 1322.9 4882.0
    300 2500.0 2.2 1324.7 4874.4
    350 2500.1 2.1 1301.2 4800.0
    400 2499.9 2.1 1317.3 4851.5
    450 2500.0 2.1 1317.9 4858.3
    500 2500.0 2.1 1316.3 4849.7

    Ez a 2.5 GHz-es Core2 mérése:
    - ami nem látszik, 2.1 IPC mellett 2.5 uop/cycle (cmovcc...)
    - ami látszik: stabilan 4800 feletti non-fused és 1300 feletti fused uop/cycle (utóbbi 2 végrehajtót dolgoztat), azaz 4800+1300*2 = 7400, a branch misprediction-ok mellett is minden órajelben 3 feldolgozó dolgozik a 6-ból.

    {@08} { x1 } and eax,00h
    {1-} mov esi,ebp
    {2} movsx ecx,byte ptr [edx]
    @init:
    {@10} mov [edi+esi*08h+__0STARROW],eax
    {1} mov [edi+esi*08h+__COLMODIFIER],eax
    {2*} add esi,04h
    {0*} jnz @init { clears ESI register }
    inc edx
    { x1 } lea ebx,[ebp+00h]
    @@ARGUMENT:
    {@20} cmp ecx,esi { 5 AGU + 10 EX uops on Kaveri }
    {1} lea eax,[ebx+ecx*04h]
    {2} movsx ecx,[edx]
    {0} mov [edi+eax*08h+__0STARROW],ebx { __0COUNTER <- EBP }
    {1} cmovs eax,esi
    {2} inc edx
    {0} mov [edi+ebp*08h+__FIXEDROW],eax
    {1} mov [edi+ebp*08h+__0STAR],eax
    {2*} add ebp,04h
    {0*} jnz @@ARGUMENT { clears EBP register }
    { -} mov edx,ebx
    { -} mov eax,edi
    {@40*} add ebp,ebx
    { *} jnz @chk0row { forced conditional jump for Sandy Bridge }
    { x5 } mov ecx,00000000h
    @@REDUCE_ROWS:
    {@49} mov [edi+edx*08h+__ROWMODIFIER],ecx
    {1*} add edx,04h
    {@50*} jz @@REDUCE_COLUMNS
    @chk0row:
    {0-} xor ecx,ecx
    {1} sub eax,ebp
    {2**} test [edi+edx*08h+__0STAR],ebp
    {0**} js @@REDUCE_ROWS
    { -} mov ebx,ebp
    { } not ecx
    {@60} @findrowmin: { 2 AGU + 5 EX uops on Kaveri }
    {0} mov esi,[eax+ebx]
    {1} or esi,[edi+ebx*08h+__0STARROW]
    {2} cmp esi,ecx
    {0} cmovb ecx,esi
    {1*} add ebx,04h
    {2*} jnz @findrowmin
    {@70-} neg ecx
    {1} jle @@REDUCE_ROWS
    @@ABNORMAL_EXIT:
    {@74} { x2 } mov edx,0FFFFFFFFh
    {1} mov esi,[esp+__MARKS]
    {2-} { x3 } cmp edi,00h
    {@80} { x6 } test ebp,0FFFFFFFFh
    {1} mov [esi+TRESULT.OPTIMUM],edx
    {2} mov ebx,[esi+TRESULT.NEXTIVALUE]
    {0} jmp dword ptr [esp+_INVALIDRESULT]
    {@90} @initcol:
    {0} mov [edi+ebp*08h+__INITCOL],ecx
    {1} add esp,ebp
    {2-} mov eax,ebp
    {0} push ebp
    {1} jmp @@1ST_STEP { long jump instruction }
    { x2 } xor edx,edx
    {@A0} { x6 } test ebp,0FFFFFFFFh
    {@A6} @setcolmod:
    { } mov [edi+edx*08h+__COLMODIFIER],ecx
    @@REDUCE_COLUMNS:
    {@AA} lea ecx,[edx-04h] { negative for minimum }
    {@AD} @chk0col:
    {0} sub edx,04h
    {@B0**} cmp edx,ebp
    {2**} jb @initcol { EDX always negative } { jb = jl for 2 negative numbers }
    {0**} test [edi+edx*08h+__0STARROW],ebp
    {1**} js @chk0col
    { } lea ebx,[edi+edx]
    { -} mov esi,ebp
    { } sub ebx,ebp
    {@C0} @findcolmin:
    {0} mov eax,[ebx] { 3 AGU + 7 EX uops on Kaveri }
    {1} add eax,[edi+esi*08h+__ROWMODIFIER]
    {2} or eax,[edi+esi*08h+__FIXEDROW]
    {0} sub ebx,ebp
    {1} cmp eax,ecx
    {2} cmovb ecx,eax
    {0*} add esi,04h
    {1*} jnz @findcolmin
    { } lea esi,[ebp-04h]
    { } lea ebx,[edi+edx]
    { **} test ecx,ecx { JS/JNS can only fuse with TEST }
    { **} js @@ABNORMAL_EXIT
    {@E0} @subcol:
    {0*} add esi,04h
    {1*} jz @setcolmod
    {2} sub ebx,ebp
    {0} mov eax,[ebx]
    {1} add eax,[edi+esi*08h+__ROWMODIFIER]
    {2**} cmp eax,ecx
    {@EF**} jnz @subcol
    { **} test [edi+esi*08h+__0STAR],ebp
    { **} js @subcol
    { } mov [edi+edx*08h+__0STARROW],esi
    { } mov [edi+esi*08h+__0STAR],edx
    { } jmp @setcolmod
    { --------------------------------------------------------------------------------------------- }
    {@00} { x16 } ...
    @@5TH_STEP:
    {@10} mov ebx,[edi+ebp*08h+__INITCOL]
    {1-} xor eax,eax
    {2} mov esi,[esp+__SIZE]
    {0-} xor ebp,ebp
    {1} mov ecx,[edi+__MINCOLROW]
    {2-} { x1 } nop
    {@20} @DEC5_free_col: { 4 AGU + 6 EX uops on Kaveri }
    {0} add [edi+ebx*08h+__COLMODIFIER],ebp
    {1-} mov ebp,eax
    {2} test [edi+ebx*08h+04h*08h+__COLMARK],ebx
    {0} cmovns ebp,edx
    {1*} add ebx,04h
    {@30*} jnz @DEC5_free_col { clears EBX register }
    { } mov eax,[esp+__SIZE+esi*04h]
    { } movsx ebx,cx
    { } sar ecx,10h
    { } jmp @INC5_marked_row
    { x2 } nop; nop
    {@40} @inc5row:
    {0} add [edi+eax*08h+__ROWMODIFIER],edx
    {1-} mov eax,ebp
    @INC5_marked_row: { 4 AGU + 4 EX uops on Kaveri }
    {2} mov ebp,[esp+esi*04h]
    {0*} sub esi,01h
    {1*} jge @inc5row { sets ESI to 0FFFFFFFFh }
    @@3RD_STEP:
    {@4E*} and esi,[edi+ebx*08h+__0STAR]
    {@52*} jz @4TH_STEP { long jump instruction }
    {0} mov [edi+ebx*08h+__0COLON___ROWMARK],ecx { set row mark }
    {@5C} @re3start:
    {0} mov ecx,[edi+ebp*08h+__INITCOL] { lea ecx,[ebp-04h] }
    {@60-} mov edx,ebp
    {@62} @mark3row:
    {0} mov [esp+__OFFS+eax*04h],ebx
    {1} mov [edi+esi*08h+__COLMARK],eax { clear __COLMARK sign = store positive value to __COLMARK}
    {2} add eax,01h
    @@2ND_STEP:
    {@6D} mov [esp+__SIZE],eax
    @chk2col:
    {@71*} add ecx,04h
    {1*} jz @@5TH_STEP
    {2**} test [edi+ecx*08h+__COLMARK],ecx { STORE FORWARDED from @mark3row }
    {0**} js @chk2col
    {12} push dword ptr [edi+ecx*08h+__COLMODIFIER]
    {@80-} mov ebx,ebp
    {0-} mov eax,ecx
    {1} sal ecx,10h
    {2} sub eax,ebp
    {@89} @ZERO2col: { 4 AGU + 11 EX uops on Kaveri }
    {0} mov esi,[edi+ebx*08h+__ROWMODIFIER]
    {1} sub esi,[esp+00h]
    {@90} add esi,[edi+eax]
    {0} jo @overflow { overflow: (-x)+(-y)=(+z) or (+x)+(+y)=(-z) }
    {1} or esi,[edi+ebx*08h+__0COLON___ROWMARK]
    {2} jz @zero
    {0} sub eax,ebp
    {1} cmp esi,edx
    {@9F} cmovb edx,esi
    {@A2} cmovb cx,bx
    @over2flow:
    {1*} add ebx,04h
    {2*} jnz @ZERO2col
    {@AB} @zero:
    {0} add esp,04h
    {1-} mov eax,ecx
    {@B0} sar ecx,10h
    {0} cmovnc eax,[edi+__MINCOLROW]
    {1} mov [edi+__MINCOLROW],eax
    {2**} test ebx,ebx
    {0**} jz @chk2col
    {@BE*} add esi,[edi+ebx*08h+__0STAR] { zero found -> ESI=0 }
    {@C2*} jz @4TH_STEP
    {0} mov eax,[esp+__SIZE]
    {1} mov [edi+ebx*08h+__0COLON___ROWMARK],ecx { set row mark }
    {2**} cmp word [edi+__MINCOLROW],bx { STORE FORWARDED }
    {@D0**} jz @re3start
    {1} cmp esi,ecx
    {2} cmovl ecx,esi
    {0*} sub ecx,04h { never clears ECX register }
    {1*} jnz @mark3row { forced conditional jump for Sandy Bridge }
    @overflow:
    sub eax,ebp
    jmp @over2flow
    @@4TH_STEP: { 5 AGU + 3 EX uops on Kaveri }
    {@E0-} mov ebx,edx
    @4TH_STEP:
    {@E2} mov edx,[edi+ecx*08h+__0STARROW]
    {2} mov [edi+ebx*08h+__0STAR],ecx
    {0} mov [edi+ecx*08h+__0STARROW],ebx
    {1} mov ecx,[edi+edx*08h+__0COLON___ROWMARK]
    {@F0**} cmp edx,00h
    {0**} jnz @@4TH_STEP
    { } mov ecx,[edi+ebp*08h+__INITCOL] { lea ecx,[ebp-04h] }
    { -} mov eax,ebp
    { } { x2 } mov edx,0FFFFFFFFh
    @@1ST_STEP: { 4 AGU + 6 EX uops on Kaveri }
    {@00} mov ebx,[edi+eax*08h+__0STARROW]
    {1} mov [edi+eax*08h+__COLMARK],ebx
    {2} and edx,ebx
    {0} mov ebx,[edi+eax*08h+__FIXEDROW]
    {1} cmovs ecx,eax
    {@10} mov [edi+eax*08h+__0COLON___ROWMARK],ebx
    {0*} add eax,04h
    {1*} jnz @@1ST_STEP { clears EAX register }
    { } xor edx,ebp { long jump instruction }
    { } js @@2ND_STEP { ===>>> EAX:00h EDX:negative ECX:initcol (>= EBP-4) }
    {@21} lea eax,[ebp-04h]
    {1-} mov edx,ebp
    {2-} xor ecx,ecx
    {0} sub esp,eax
    {1-} mov ebx,edi { work matrix unmodified } { [esp+__SAVE] }
    {2} mov esi,[esp+__MARKS]
    @@results:
    {@30} mov eax,[edi+edx*08h+__0STAR]
    {1} sub ebx,ebp
    {2} add ecx,[ebx+eax]
    {0} sub eax,ebp
    {1} shr eax,02h
    {2} mov [esi],al
    {@40} add esi,01h
    {1*} add edx,04h
    {2*} jnz @@results

    [ Szerkesztve ]

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #98 üzenetére

    Core2-n továbbra is 506000 mátrix oldódik meg 60 sec alatt. Meg is van a magyarázat, pipeline szimuláció szerint, a fő ciklusra, 5 db lefutás (tárolás nincs benne, azaz 4 pipe dolgozik csak):

    sub esi,[esp+00h] add esi,[eax+ebp] lea eax,[eax+ebp] jo @over2flow
    or esi,[...+__0COLON___ROWMARK] jz @zero cmp esi,edx
    cmovb edx,esi
    cmovb cx,bx mov esi,[...+__ROWMODIFIER] add ebx,04h jnz @ZERO2col


    clk -- ALO 0 -- | -- ALU 1 -- | -- ALU 5 -- | -- LOAD --
    00 | lea eax,[eax+ebp] | | ld x,esp+00h
    01 | | | ld y,eax+ebp
    02 | | | ld z,rowmark
    03 sub esi,x | add ebx,04h | | mov esi,rowmodifier
    04 add esi,y | lea eax,[eax+ebp] | jnz @zeroincol | ld x,esp+00h
    05 or esi,z | | jo overflow | ld y,eax+ebp
    06 cmp esi,edx | | jz zero | ld z,rowmark
    07 cmovb cx,bx | cmovb edx,esi | sub esi,x | mov esi,rowmodifier
    08 cmovb cx,bx | cmovb edx,esi | add esi,y | ld x,esp+00h
    09 or esi,z | add ebx,04h +2 | jz @zero | ld y,eax+ebp
    10 cmp esi,edx | cmovb edx,esi | jo @overflow | ld z,rowmark
    11 cmovb cx,bx | cmovb edx,esi | jnz @zeroincol +4 | mov esi,rowmodifier
    12 sub esi,x +1 | lea eax,[eax+ebp] +1 | | ld x,esp+00h
    13 add esi,x +1 | add ebx,04h +2 | | ld y,eax+ebp
    14 or esi,z +1 | | jo overflow +1 | ld z,rowmark
    15 cmp esi,edx | sub esi,x | jz @zero +1 | mov esi,rowmodifier
    16 cmovb cx,bx | cmovb esi,edx | jnz @zeroincol +4 | ld x,esp+00h
    17 cmovb cx,bx | cmovb esi,edx | add esi,y |
    18 or esi,z | lea eax,[eax+ebp] +2 | jo overflow |
    19 cmp esi,edx | add ebx,04h +4 | jz @zero | ld y,eax+ebp
    20 cmovb cx,bx | cmovb esi,edx | jnz @zeroincol | ld z,rowmark
    21 cmovb cx,bx | cmovb esi,edx | sub esi,x +2 | mov esi,rowmodifier
    22 add esi,y | lea eax,[eax+ebp] +2 | |
    23 or esi,z | add ebx,04h | jo overflow |
    24 cmp edx,esi | | jz @zero |
    25 cmovb cx,bx | cmovb esi,edx | jnz @zeroincol |
    26 cmovb cx,bx | cmovb esi,edx | |

    27 órajel alatt indul el az 5 ciklus 60 utasítása, ez 2,22 IPC; pontosan annyi, amennyi a programon mérhető (a szimuláció 3 clock/load-dal történt). A "+x" jelölés azt jelenti, hogy az adott uop hány órajellel később indul el ahhoz képest , hogy a paraméterei rendelkezésre állnak, mivel van öregebb lefuttatni való uop, ami akadályozza. Nem csoda a 2,2 IPC és a "röcögés", mert főleg az add ebx,04h és kisebb mértékben a lea eax,[eax+ebp] az érintett, amelyek épp a következő ciklusmag lefutását késleltetik (a jcc utasítások ilyen szempontből lényegtelenek, mivel a decode fázisban "kezeli le" őket a branch prediction).

    Ha az X*X méretű munkamátrix végére egy plusz sor kerülne, amely csupa nullát tartalmaz, akkor az add ebx,04h + jnz @zeroincol párosnak nem kellene lezárónak lennie a ciklusban, a felső jz @zero kiléptetné, így az add ebx,04h bárhol elhelyezhető lenne a ciklusban, ezzel az add ebx,04h "öregebb" lenne, így nagyobb IPC érhető el.
    Meglátjuk.

    [ Szerkesztve ]

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #99 üzenetére

    Nem ez a gond; bár a szimuláció a végrehajtásra jó, a Core-ok utasításdekódolása teljesen másképp működik, mint az AMD-knél a fixen egymás után következő 3 (K7/K8/K10) vagy 4 (Bulldozer-family) utasítás mint egy egység.

    Az említett 12 utasításos (14 uop, ebből 13 ALU-érintett) ciklusmag 2.5 IPC-vel (2.9 uop/clk) fut (2.5 GHz mellett 1500 fused + 5600 non-fused uop = 3,44 művelet/órajel; tekintve, hogy tárolás nincs benne, azaz 4 pipe-ot mozgat (p2 mint load és a p015 3 ALU), ez nagyon közel van az elméleti maximumhoz; ennél több nehezen hozható ki belőle).

    Nem is kellene említem, hogy K10-en a K10-utasítássorrendű ciklus természetesen 3.0 IPC-vel megy.

    Bár még programot egyelőre nehéz írni/átrendezni rá, kezd kézzelfoghatóvá válni, hogy mit és hogyan dekódol a Core2 (és miért kellett a garantált 4 uop/clock a későbbi Core-verziókba). Pl. ezt a ciklusmagot 3 órajel alatt dekódolja a Core 2 (IPC 2.6, 3.0 uop/cycle), pedig ránézésre ráhúzható a 4-1-1-1 + 4-1-1-1 minta:

    mov eax,[edi+esi*08h+__0STARROW]
    mov [edi+esi*08h+__COLMARK],eax
    and ebx,eax
    mov eax,[edi+esi*08h+__FIXEDROW]
    cmovs ecx,esi
    mov [edi+esi*08h+__0COLON___ROWMARK],eax
    add esi,04h
    jnz @@1ST_STEP

    Érdekesebb, hogy ezt is 3 órajel alatt dekódolja (IPC 2.3, 2.9 uop/cycle), pedig 2-1-1 + 2-1-1 a mintája:

    add [edi+ebx*08h+__COLMODIFIER],ebp
    mov ebp,[edi+ebx*08h+(04h*08h)+__COLMARK]
    xor ebp,edx
    cmovs ebp,ecx
    add ebx,04h
    jnz @DEC5_free_col

    A cmovcc, a load-op-store mindenképpen a 0. dekóderre kell kerüljön, illetve csak egymás utáni utasításokat tud dekódolni a Core2.

    [ Szerkesztve ]

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #101 üzenetére

    Eheti 1000-mátrix-hetente rovat :)

    Core2 (2.5 GHz): 60 sec alatt 510000 mátrix

    {@04-} { x1 } movsx ebx,byte ptr es:[edx]
    {1-} xor eax,eax
    {2-} mov esi,ebp
    {0} and esi,-8
    @init:
    {@0F} mov [edi+esi*08h+(00h*08h)+__0STARROW],eax
    {1} mov [edi+esi*08h+(04h*08h)+__0STARROW],eax
    {2*} add esi,08h
    {0*} jnz @init { clears ESI register }
    { } add edx,01h
    { -} mov ecx,ebp
    @@ARGUMENT: { K10:2.6 Core2:2.9 - 3.3 uop/clk - 1640*2+6550 }
    {@20} cmp ebx,esi { 4 AGU + 9 EX uops on Kaveri }
    {1} lea eax,[ebp+ebx*04h+00h] { 3 clk 8 ALU ops on Core 2 }
    {2} movsx ebx,[edx]
    {0} lea edx,[edx+01h]
    {1} mov [edi+eax*08h+__0STARROW],ebp { __0COUNTER <- EBP }
    {2} cmovs eax,esi
    {0} mov [edi+ecx*08h+__FIXEDROW],eax
    {1*} add ecx,04h
    {2*} jnz @@ARGUMENT { clears ECX register }
    { } add esp,ebp
    { -} mov eax,edi
    { -} push ebp
    {@40-} lea edx,[ebp-04h]
    @@REDUCE_ROWS:
    {@43} mov [edi+edx*08h+__ROWMODIFIER],ecx
    {1} mov esi,[edi+edx*08h+(04h*08h)+__FIXEDROW]
    {2*} add edx,04h
    {0*} jz @@REDUCE_COLUMNS
    {@50} mov [edi+edx*08h+__0STAR],esi
    {2-} xor ecx,ecx
    {0} sub eax,ebp
    {1**} test esi,esi { JS/JNS can only fuse with TEST }
    {2**} js @@REDUCE_ROWS
    { -} mov ebx,ebp { EBX < 0 for even minimum }
    { } mov ecx,[eax+ebp]
    {@61} or ecx,[edi+ebp*08h+__0STARROW]
    { } and ebp,04h
    { } add ebp,ebx
    {@69} @findrowmin: { K10:2.8 Core2:2.2 - 2.6 uop/clk - 1100*2+5000 }
    {0} mov esi,[eax+ebp+00h] { 4 AGU + 8 EX uops on Kaveri }
    {1} or esi,[edi+ebp*08h+(00h*08h)+__0STARROW] { 3 clk 10 ALU ops on Core 2 }
    {2} add ebp,08h
    {@72} cmp esi,ebx
    {1} cmovb ebx,esi
    {2} mov esi,[eax+ebp-04h]
    {0} or esi,[edi+ebp*08h-(04h*08h)+__0STARROW]
    {1} cmp esi,ecx
    {@81} cmovb ecx,esi
    {0**} test ebp,ebp
    {1**} jnz @findrowmin
    { } mov ebp,[esp+00h]
    { } cmp ebx,ecx
    { } cmovb ecx,ebx
    {@90} neg ecx
    { } jle @@REDUCE_ROWS
    @@ABNORMAL_EXIT:
    {@94} pop eax
    {1} sub esp,ebp
    {2} mov edx,0FFFFFFFFh
    {0} mov esi,[esp+__MARKS]
    {@A0} mov [esi+TRESULT.OPTIMUM],edx
    {2} mov ebx,[esi+TRESULT.NEXTIVALUE]
    {0} jmp dword ptr [esp+_INVALIDRESULT]
    { } { x6 } test ebp,0FFFFFFFFh
    {@90} @initcol:
    {0} neg dword ptr [esp+00h]
    {1-} mov esi,ebp
    {2} neg ebp
    {0} mov [edi+__INITCOL],ecx
    {1} or ebx,-1
    {2} jmp @@1ST_STEP { long jump instruction }
    {@A2} @free0col:
    { } lea ecx,[edx-04h]
    {@A5} @setcolmod:
    { } mov [edi+edx*08h+__COLMODIFIER],esi
    @@REDUCE_COLUMNS:
    {1**} jz @initcol
    {0} sub edx,04h
    {@B0-} xor esi,esi
    {1**} test [edi+edx*08h+__0STARROW],ebp
    {2**} js @setcolmod
    { } lea ebx,[edi+edx]
    { -} mov ecx,ebp
    { -} mov eax,ebp
    { } sub ebx,ebp
    {@C0} @findcolmin: { K10:3.0 Core2:_._ - _._ uop/clk - ____*2+____
    {0} mov esi,[ebx] { 3 AGU + 8 EX uops on Kaveri }
    {1} add esi,[edi+ecx*08h+__ROWMODIFIER] { 3 clk 9 ALU ops on Core 2 }
    {2} or esi,[edi+ecx*08h+__FIXEDROW]
    {0} jz @test0row
    {1} sub ebx,ebp
    {2} cmp esi,eax
    {@D0} cmovb eax,esi
    {1*} add ecx,04h
    {2*} jnz @findcolmin
    { } lea ecx,[ebp-04h]
    { -} mov esi,eax
    { } lea ebx,[edi+edx]
    {@E0**} test eax,eax { JS/JNS can only fuse with TEST }
    { **} js @@ABNORMAL_EXIT
    {@E4} @seekcol0:
    {0} mov eax,[edi+ecx*08h+(04h*08h)+__ROWMODIFIER]
    {1*} add ecx,04h
    {2*} jz @free0col
    {0} sub ebx,ebp
    {1} add eax,[ebx]
    {@F1**} cmp eax,esi { maximum data value = 00FFFFFFh -> marked elements stay negative }
    {0**} jnz @seekcol0
    @test0row:
    { **} test [edi+ecx*08h+__0STAR],ebp
    { **} js @seekcol0
    { } mov [edi+edx*08h+__0STARROW],ecx
    {@FE} mov [edi+ecx*08h+__0STAR],edx
    {@02} jns @free0col { forced conditional jump for Sandy Bridge }
    { ----------------------------------------------------------------------------------------------- }
    {@04} { x12 } mov eax,00000000h; mov edx,00000000h; xor ebp,ebp
    {@10} { x5 } mov ecx,00000000h
    @@5TH_STEP: { K10:2.6 Core2:2.4 - 2.8 uop/clk - 2000*2+5100
    {@15} mov eax,[edi+__INITCOL] { lea eax,[ebp+04h]; neg eax }
    {1} mov esi,[esp+__SIZE]
    {2} movsx ebx,word ptr [edi+__MINCOLROW]
    {@20} @DEC5_free_col: { 3 AGU + 6 EX uops on Kaveri }
    {0} add [edi+eax*08h+__COLMODIFIER],ecx { 2 clk 5 ALU ops on Core 2 }
    {1} mov ecx,[edi+eax*08h+(04h*08h)+__COLMARK]
    {2} sar ecx,1Fh
    {0} and ecx,edx
    {1*} add eax,04h
    {@30*} jnz @DEC5_free_col { clears EAX register [NOT USED] }
    { } mov eax,[esp+__SIZE+esi*04h]
    { } movsx ecx,word ptr [edi+__MINCOLROW+02h]
    { } jmp @INC5_marked_row
    { x4 } xor ebp,ebp; xor esi,esi
    {@40} @inc5row:
    {0} add [edi+eax*08h+__ROWMODIFIER],edx { 4 AGU + 4 EX uops on Kaveri }
    {1-} mov eax,ebp
    @INC5_marked_row:
    {2} mov ebp,[esp+esi*04h]
    {0*} sub esi,01h
    {1*} jge @inc5row { sets ESI to 0FFFFFFFFh }
    @@3RD_STEP:
    {@4E*} and esi,[edi+ebx*08h+__0STAR]
    {@52*} jz @4TH_STEP { long jump instruction }
    {@58} @re3start:
    { } mov [edi+ebx*08h+__0COLON___ROWMARK],ecx { set row mark }
    { } { x1 } mov ecx,es:[edi+__INITCOL] { lea ecx,es:[ebp-04h] }
    {@60-} mov edx,ebx
    {@62} @mark3row:
    { } mov [esp+__OFFS+eax*04h],ebx
    { -} xor ebx,ebx
    { } mov [edi+esi*08h+__COLMARK],esi { unmark column with negative }
    { } inc eax
    { } mov [esp+__SIZE],eax
    {@71} @chk2col:
    {0*} add ecx,04h
    {1*} jz @@5TH_STEP { clears ECX register }
    {2**} test [edi+ecx*08h+__COLMARK],ecx { STORE FORWARDED from @mark3row }
    {0**} jns @chk2col
    @@2ND_STEP:
    {12} push dword ptr [edi+ecx*08h+__COLMODIFIER]
    {@80} lea eax,[ecx+edi]
    { } sub ebx,ebp
    { } sal ecx,10h
    { } mov esi,[edi+ebx*08h+__ROWMODIFIER]
    {@8C} @ZERO2col: { K10:3.0 Core2:2.5 - 2.9 uop/clk - 1500*2+5600 { 4 AGU + 11 EX uops on Kaveri }
    {0} sub esi,[esp+00h] { 4 clk 13 ALU ops on Core 2 }
    {@8F} add esi,[eax+ebp]
    {C2D} lea eax,[eax+ebp] { Core 2, Kaveri }
    {2} jo @over2flow { overflow: (-x)+(-y)=(+z) or (+x)+(+y)=(-z) }
    {0} or esi,[edi+ebx*08h+__0COLON___ROWMARK]
    {1} jz @zero
    {K10}// lea eax,[eax+ebp] { K10, Sandy Bridge, Ivy Bridge }
    {0} cmp esi,edx
    {@9F} cmovb edx,esi
    {@A2} cmovb cx,bx
    @over2flow:
    {0} mov esi,[edi+ebx*08h+(04h*08h)+__ROWMODIFIER]
    {1*} add ebx,04h
    {2*} jnz @ZERO2col { clears EBX register }
    {@AF} @zero:
    {0} pop eax { add esp,04h } { forces ESP handling to AGU/memory pipe on Kaveri/Core }
    {@B0-} mov eax,ecx
    {2} sar ecx,10h
    {0} cmovnc eax,[edi+__MINCOLROW]
    {1} mov [edi+__MINCOLROW],eax
    {2**} test ebx,ebx
    {0**} jz @chk2col
    {@C0*} add esi,[edi+ebx*08h+__0STAR] { zero found -> ESI=0 }
    {2*} jz @4TH_STEP
    {0} cmp ax,bx
    {1} { x1 } mov eax,ss:[esp+__SIZE]
    {2} jz @re3start
    {@D0} cmp esi,ecx
    {1} mov [edi+ebx*08h+__0COLON___ROWMARK],ecx { set row mark }
    {2} cmovl ecx,esi
    {0*} sub ecx,04h { never clears ECX register }
    {1*} jnz @mark3row { forced conditional jump for Sandy Bridge }
    { x2 } xor esi,esi
    {@E0} { x4 } lea eax,[ebp+ebp+00h]
    @@4TH_STEP: { 5 AGU + 3 EX uops on Kaveri }
    {@E4-} mov ebx,edx { 2 clk 2 ALU ops on Core 2 }
    @4TH_STEP:
    {@E6} mov edx,[edi+ecx*08h+__0STARROW]
    {2} mov [edi+ebx*08h+__0STAR],ecx
    {0} mov [edi+ecx*08h+__0STARROW],ebx
    {@F0} mov ecx,[edi+edx*08h+__0COLON___ROWMARK]
    {2**} cmp edx,00h
    {0**} jnz @@4TH_STEP { clears EDX register }
    { } sub esi,ebp
    { } sub edx,ebp
    { } lea ecx,[esi-04h] { mov ecx,[edi+__INITCOL] }
    @@1ST_STEP: { K10:2.8 Core2:2.9 - 3.2 uop/clk - 1500*2+6100 }
    {@00} mov eax,[edi+esi*08h+__0STARROW] { 4 AGU + 7 EX uops on Kaveri }
    {1} and ebx,eax { 3 clk 6 ALU ops on Core 2 }
    {2} not eax
    {0} mov [edi+esi*08h+__COLMARK],eax
    {1} mov eax,[edi+esi*08h+__FIXEDROW]
    {2} cmovs ecx,esi
    {0} mov [edi+esi*08h+__0COLON___ROWMARK],eax
    {1*} add esi,04h
    {2*} jnz @@1ST_STEP { clears ESI register }
    { } mov [esp+__SIZE],esi
    { -} xor ebx,ebx
    {@21*} add ecx,04h { long jump instruction }
    { *} jnz @@2ND_STEP { ===>>> EBX: 00h EDX:negative ECX:initcol (>= EBP) }
    { } mov esi,[esp+ebp+04h+__MARKS]
    { -} mov ebx,edi { work matrix unmodified } { [esp+__SAVE] }
    @@results:
    {@30} mov eax,[edi+edx*08h+__0STAR] { 3 AGU + 8 EX uops on Kaveri }
    {1} add ebx,ebp
    {2} add ecx,[ebx+eax]
    {0} add eax,ebp
    {1} shr eax,02h
    {2} mov [esi],al
    {@40} add esi,01h
    {1*} add edx,04h
    {2*} jnz @@results { clears EDX register ( DL=0 as head, DH=0 as length ) }
    {0} pop eax
    {1} add esp,ebp
    {2} neg ebp
    {0} or eax,-1
    {@50} lea ebx,[edi+ebp*04h]
    {1} sar ebp,02h
    {2} mov [esi+ebp+TRESULT.OPTIMUM],ecx
    {0} add esi,ebp
    {1-} xor ecx,ecx
    {2} jmp @onchain

    [ Szerkesztve ]

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #102 üzenetére

    Core2 (2.5 GHz): 59 sec alatt megoldja a feladatot
    K10 (2.9 GHz): Core2-nek tetsző ciklusverzióval 46 sec oldja meg a feladatot
    Prescott (2.26 GHz): 60 sec alatt 220000 mátrix

    {@04-} { x1 } movsx ebx,byte ptr es:[edx]
    {1-} xor eax,eax
    {2-} mov esi,ebp
    {0} and esi,-8
    @init:
    {@0F} mov [edi+esi*08h+(00h*08h)+__0STARROW],eax
    {1} mov [edi+esi*08h+(04h*08h)+__0STARROW],eax
    {2*} add esi,08h
    {0*} jnz @init { clears ESI register }
    { } add edx,01h
    { -} mov ecx,ebp
    @@ARGUMENT: { K10:2.6 Core2:2.9 - 3.3 uop/clk - 1640*2+6550 }
    {@20} cmp ebx,esi { 4 AGU + 9 EX uops on Kaveri }
    {1} lea eax,[ebp+ebx*04h+00h] { 3 clk 8 ALU ops on Core 2 }
    {2} movsx ebx,[edx]
    {0} lea edx,[edx+01h]
    {1} mov [edi+eax*08h+__0STARROW],ebp { __0COUNTER <- EBP }
    {2} cmovs eax,esi
    {0} mov [edi+ecx*08h+__FIXEDROW],eax
    {1*} add ecx,04h
    {2*} jnz @@ARGUMENT { clears ECX register }
    { -} { x2 } xor ecx,ecx
    { -} mov eax,edi
    { -} push ebp
    {@40-} lea edx,[ebp-04h]
    @@REDUCE_ROWS:
    {@43} mov [edi+edx*08h+__ROWMODIFIER],ecx
    {1} mov esi,[edi+edx*08h+(04h*08h)+__FIXEDROW]
    {2*} add edx,04h
    {0*} jz @@REDUCE_COLUMNS
    {@50} mov [edi+edx*08h+__0STAR],esi
    {2-} xor ecx,ecx
    {0} sub eax,ebp
    {1**} test esi,esi { JS/JNS can only fuse with TEST }
    {2**} js @@REDUCE_ROWS
    { -} mov ebx,ebp { EBX < 0 for even minimum }
    { } mov ecx,[eax+ebp]
    {@61} or ecx,[edi+ebp*08h+__0STARROW]
    { } and ebp,04h
    { } add ebp,ebx
    {@69} @findrowmin: { K10:2.8 Core2:2.2 - 2.6 uop/clk - 1100*2+5000 }
    {0} mov esi,[eax+ebp+00h] { 4 AGU + 8 EX uops on Kaveri }
    {1} or esi,[edi+ebp*08h+(00h*08h)+__0STARROW] { 3 clk 10 ALU ops on Core 2 }
    {2} add ebp,08h
    {@72} cmp esi,ebx
    {1} cmovb ebx,esi
    {2} mov esi,[eax+ebp-04h]
    {0} or esi,[edi+ebp*08h-(04h*08h)+__0STARROW]
    {1} cmp esi,ecx
    {@81} cmovb ecx,esi
    {0**} test ebp,ebp
    {1**} jnz @findrowmin
    { } mov ebp,[esp+00h]
    { } cmp ebx,ecx
    { } cmovb ecx,ebx
    {@90} neg ecx
    { } jle @@REDUCE_ROWS
    { -} nop
    @@ABNORMAL_EXIT:
    {@95} pop eax
    {1} or edx,-1
    {2} mov esi,[esp+__MARKS]
    {0} mov [esi+TRESULT.OPTIMUM],edx
    {@A0} mov ebx,[esi+TRESULT.NEXTIVALUE]
    {2} jmp dword ptr [esp+_INVALIDRESULT]
    { } { x6 } test ebp,0FFFFFFFFh
    {@AD} @init0col:
    {0} mov [edi+__INITCOL],ecx
    {@B0-} mov esi,ebp
    {2} neg ebp
    {0} or ebx,-1
    {1*} sub ecx,04h
    {2*} jnz @@1ST_STEP { long jump instruction } { forced conditional jump for Sandy Bridge }
    {@C0} { x3 } cmp ebp,00h
    {@C3} @free0col:
    { -} mov ecx,edx
    {@C5} @setcolmod:
    { } mov [edi+edx*08h+__COLMODIFIER],esi
    @@REDUCE_COLUMNS: { no need to initialize -initcol in ECX }
    {0**} cmp edx,ebp
    {1**} jz @init0col
    {0} sub edx,04h
    {@D0-} xor esi,esi
    {1**} test [edi+edx*08h+__0STARROW],ebp
    {2**} js @setcolmod
    { } lea ebx,[edi+edx]
    { -} mov ecx,ebp
    { -} mov eax,ebp
    { } sub ebx,ebp
    {@E0} @findcolmin: { K10:3.0 Core2:_._ - _._ uop/clk - ____*2+____
    {0} mov esi,[ebx] { 3 AGU + 8 EX uops on Kaveri }
    {1} add esi,[edi+ecx*08h+__ROWMODIFIER] { 3 clk 9 ALU ops on Core 2 }
    {2} or esi,[edi+ecx*08h+__FIXEDROW]
    {0} jz @test0row
    {1} sub ebx,ebp
    {2} cmp esi,eax
    {@F0} cmovb eax,esi
    {1*} add ecx,04h
    {2*} jnz @findcolmin
    { } lea ecx,[ebp-04h]
    { -} mov esi,eax
    { } lea ebx,[edi+edx]
    {@00**} test eax,eax { JS/JNS can only fuse with TEST }
    { **} js @@ABNORMAL_EXIT
    {@04} @seekcol0:
    {0} mov eax,[edi+ecx*08h+(04h*08h)+__ROWMODIFIER]
    {1*} add ecx,04h
    {2*} jz @free0col
    {0} sub ebx,ebp
    {1} add eax,[ebx]
    {@11**} cmp eax,esi { maximum data value = 00FFFFFFh -> marked elements stay negative }
    {0**} jnz @seekcol0
    @test0row:
    { **} test [edi+ecx*08h+__0STAR],ebp
    { **} js @seekcol0
    { } mov [edi+edx*08h+__0STARROW],ecx
    {@1E} mov [edi+ecx*08h+__0STAR],edx
    {@22} jns @free0col { forced conditional jump for Sandy Bridge }
    { ----------------------------------------------------------------------------------------------- }
    {@24} { x12 } test ebp,0FFFFFFFFh; test edi,0FFFFFFFFh
    {@30} { x9 } mov ecx,00000000h; xor esi,esi; xor edi,edi
    @@5TH_STEP: { K10:2.6 Core2:_._ - _._ uop/clk - ____*2+____
    {@39} mov ecx,[edi+__MINCOLROW]
    { } sub ebx,ebp
    { } neg edx
    {@40} @DEC5_free_col: { 5 AGU + 11 EX uops on Kaveri }
    {0} mov eax,[edi+ebx*08h+__COLMARK] { 3 clk 8 ALU ops on Core 2 }
    {1} sar eax,1Fh
    {2} mov [edi+ebx*08h+__COLMARK],eax
    {0} and eax,edx
    {1} sub [edi+ebx*08h+__COLMODIFIER],eax
    {@51} mov eax,[edi+ebx*08h+__0COLON___ROWMARK]
    {0} sar eax,1Fh
    {1} and eax,edx
    {2} sub [edi+ebx*08h+__ROWMODIFIER],eax
    {0*} add ebx,04h
    {@61*} jnz @DEC5_free_col { clears EBX register [NOT USED] }
    {@63} movsx ebx,cx
    {1} sar ecx,10h
    {2} mov esi,[edi+ebx*08h+__0STAR]
    {0**} cmp esi,00h
    {@70**} jz @4TH_STEP { long jump instruction }
    {2} mov [edi+ebx*08h+__0COLON___ROWMARK],ecx { set row mark }
    {0} mov dword ptr [edi+esi*08h+__COLMARK],0FFFFFFFFh { unmark column with -1 }
    {1} mov esi,[edi+__INITCOL]
    {@85} @mark3row:
    { -} xor ebx,ebx
    { } lea ecx,[esi-04h]
    { } jmp @chk2col
    @pass2col:
    { } mov [edi+ecx*08h+__COLMARK],ecx { re-mark column with column index <> -1 }
    {@90} @chk2col:
    {0*} add ecx,04h
    {1*} jz @@5TH_STEP { clears ECX register }
    {2**} cmp [edi+ecx*08h+__COLMARK],ecx
    {0**} jbe @chk2col
    @@2ND_STEP:
    { } lea eax,[ecx+edi]
    { } sub ebx,ebp
    @continue:
    {@A0} { x1 } push dword ptr es:[edi+ecx*08h+__COLMODIFIER]
    { } sal ecx,10h
    { } mov esi,[edi+ebx*08h+__ROWMODIFIER]
    {@AC} @ZERO2col: { K10:3.0 Core2:2.5 - 2.9 uop/clk - 1500*2+5600 { 4 AGU + 11 EX uops on Kaveri }
    {0} sub esi,[esp+00h] { 4 clk 13 ALU ops on Core 2 }
    {@AF} add esi,[eax+ebp]
    {C2D} lea eax,[eax+ebp]
    {2} jo @over2flow { overflow: (-x)+(-y)=(+z) or (+x)+(+y)=(-z) }
    {0} or esi,[edi+ebx*08h+__0COLON___ROWMARK]
    {1} jz @@3RD_STEP
    {K10}// lea eax,[eax+ebp]
    {0} cmp esi,edx
    {@BF} cmovb edx,esi
    {@C2} cmovb cx,bx
    @over2flow:
    {0} mov esi,[edi+ebx*08h+(04h*08h)+__ROWMODIFIER]
    {1*} add ebx,04h
    {2*} jnz @ZERO2col { clears EBX register }
    @@3RD_STEP:
    {@CF} pop esi { add esp,04h } { enforces ESP handling to AGU/load pipe on Kaveri/Core }
    {@D0-} mov esi,ecx
    {2} sar ecx,10h
    {0} cmovnc esi,[edi+__MINCOLROW]
    {1} mov [edi+__MINCOLROW],esi
    {2**} test ebx,ebx
    {0**} jz @pass2col
    {@E0} mov esi,[edi+ebx*08h+__0STAR]
    {2**} test esi,esi
    {0**} jz @4TH_STEP
    {1} mov [edi+ebx*08h+__0COLON___ROWMARK],ecx { set row mark }
    {2} or dword ptr [edi+esi*08h+__COLMARK],-1 { unmark column with -1 }
    {@F1**} cmp word ptr [edi+__MINCOLROW],bx
    {1**} jz @re2start
    {2**} cmp esi,ecx { jb = jl for 2 negative numbers }
    {0**} jb @mark3row
    {1*} add ebx,04h
    {2*} jnz @continue
    {@00} jmp @pass2col
    {1} { x2 } xor eax,eax
    {@04} @re2start:
    {0} mov ecx,[edi+__INITCOL]
    {1-} mov ebx,ebp
    {2} neg ebx
    @initcol:
    {0} sar dword ptr [edi+ebx*08h+__COLMARK],1Fh
    {@10*} add ebx,04h
    {2*} jnz @initcol { clears EBX register }
    { } or edx,-1
    { *} sub ecx,04h
    { *} jnz @chk2col { long jump instruction }
    {@20} { x4 } lea eax,[ebp+ebp+00h]
    @@4TH_STEP: { 5 AGU + 3 EX uops on Kaveri }
    {@24-} mov ebx,edx { 2 clk 2 ALU ops on Core 2 }
    @4TH_STEP:
    {@26} mov edx,[edi+ecx*08h+__0STARROW]
    {2} mov [edi+ebx*08h+__0STAR],ecx
    {0} mov [edi+ecx*08h+__0STARROW],ebx
    {@30} mov ecx,[edi+edx*08h+__0COLON___ROWMARK]
    {2**} cmp edx,00h
    {0**} jnz @@4TH_STEP { clears EDX register }
    { } sub esi,ebp
    { } sub edx,ebp
    { } lea ecx,[esi-04h]
    @@1ST_STEP: { K10:2.8 Core2:2.9 - 3.2 uop/clk - 1500*2+6100 }
    {@40} mov eax,[edi+esi*08h+__0STARROW] { 4 AGU + 7 EX uops on Kaveri }
    {1} and ebx,eax { 3 clk 6 ALU ops on Core 2 }
    {2} not eax
    {0} mov [edi+esi*08h+__COLMARK],eax
    {1} mov eax,[edi+esi*08h+__FIXEDROW]
    {2} cmovs ecx,esi
    {0} mov [edi+esi*08h+__0COLON___ROWMARK],eax
    {1*} add esi,04h
    {2*} jnz @@1ST_STEP { clears ESI register }
    { } { x3 } mov ebx,00000000h
    {@60*} add ecx,04h { long jump instruction }
    { *} jnz @@2ND_STEP { ===>>> EBX: 00h EDX:negative = -EBP ECX:initcol (>= EBP) }
    { } { x1 } mov esi,ss:[esp+04h+__MARKS]
    { -} mov ebx,edi { work matrix unmodified } { [esp+__SAVE] }
    @@results:
    {@70} mov eax,[edi+edx*08h+__0STAR] { 3 AGU + 8 EX uops on Kaveri }
    {1} add ebx,ebp
    {2} add ecx,[ebx+eax]
    {0} add eax,ebp
    {1} shr eax,02h
    {2} mov [esi],al
    {@80} add esi,01h
    {1*} add edx,04h
    {2*} jnz @@results { clears EDX register ( DL=0 as head, DH=0 as length ) }

    [ Szerkesztve ]

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #92 üzenetére

    Egy Pentium 4 1 nagyságrenddel nagyobb teljesítményre képes, mint egy Java-ban írt program ARM-on (legalábbis mert léteznek pointerek, nincs szigorú típusosság, nincs byte-nál automatikus előjeles kiterjesztés 4 byte-ra, amit le kell küzdeni, stb.); még úgy is, hogy a branch prediction success rate 87% körüli.

    A ciklus ASM-ben:

    @character:
    {@65} { } mov [edi],al
    { } add edi,01h
    @@DECODE:
    {@6A} { } mov eax,[esp+_aMAXMINBITS]
    @read_raw: { BPOS may be 20h since decreased soon }
    { } movzx ebp,byte ptr [esi]
    {@70} { -} mov ecx,edx
    { } sub edx,(24+1)
    { } shl ebp,cl
    { } shr edx,1Fh
    { } add esi,edx
    { } lea edx,[ecx+edx*08h]
    { } or ebx,ebp
    {@81} { **} cmp dl,al
    { **} jb @read_raw
    @createABCcode:
    { } movzx ebp,bl
    { } movzx ecx,bh
    { } shr eax,10h
    { } { x1 } mov ebp,dword ptr es:[REVERSE2hi+ebp*04h]
    { } { x1 } add ebp,dword ptr es:[REVERSE2lo+ecx*04h]
    { -} mov ecx,eax
    {@A0} { } mov eax,offset(EXT_AMINMAXCODE)
    @seekABC:
    {@A5} {0**} cmp [eax+ecx*08h+00h+_MAX],ebp
    {1**} jnbe @foundABC
    {2} cmp [eax+ecx*08h-08h+_MAX],ebp
    {0} lea ecx,[ecx-02h]
    {@B1} {1} jbe @seekABC
    { } add ecx,01h
    @foundABC:
    {@B6} {0} mov eax,[eax+ecx*08h+_MIN]
    {1} shr ebp,cl
    {2} { x1 } mov eax,es:[eax+ebp*04h]
    {@C0} {0} neg ecx
    {1} add ecx,10h
    {2} sub edx,ecx
    {0} shr ebx,cl
    {1**} cmp eax,255
    {2**} jna @character { SHORT jump instruction offset: -6Bh }
    @repeatABC:
    {@D0} {0-} mov ecx,eax
    {1} movzx ebp,ah
    {2} shr eax,10h
    {0} jz @@SECTION
    {1} sub dl,cl
    {@E0} {2} and ebp,ebx
    {0} shr ebx,cl
    {1} add ebp,eax
    {2} { x1 } mov eax,ss:[esp+_dMAXMINBITS]
    {0} add edi,ebp
    {1} neg ebp
    {2} mov [esp+_MOVELEN],ebp
    @read__raw: { BPOS may be 20h since decreased soon }
    {@F3} {0} movzx ebp,byte ptr [esi]
    {1-} mov ecx,edx
    {2} sub edx,(24+1)
    {0} shl ebp,cl
    {1} shr edx,1Fh
    {@00} {2} add esi,edx
    {0} lea edx,[ecx+edx*08h]
    {1} or ebx,ebp
    {2**} cmp dl,al
    {0**} jb @read__raw
    @createDISTcode:
    { } movzx ebp,bl
    { } movzx ecx,bh
    {@11} { } shr eax,10h
    { } { x1 } mov ebp,dword ptr es:[REVERSE2hi+ebp*04h]
    { } { x1 } add ebp,dword ptr es:[REVERSE2lo+ecx*04h]
    {@24} { -} mov ecx,eax
    { } mov eax,offset(EXT_DMINMAXCODE)
    @seekDIST:
    {0**} cmp [eax+ecx*08h+00h+_MAX],ebp
    {1**} jnbe @foundDIST
    {@90} {2} cmp [eax+ecx*08h-08h+_MAX],ebp
    {0} lea ecx,[ecx-02h]
    {1} jbe @seekDIST
    { } add ecx,01h
    @foundDIST:
    {0} mov eax,[eax+ecx*08h+_MIN]
    {@A0} {1} shr ebp,cl
    {2} mov eax,[eax+ebp*04h]
    {0} neg ecx
    {1} add ecx,10h
    {2} sub edx,ecx
    {0} shr ebx,cl
    {1**} cmp al,00h
    {@70} {2**} js @xxx
    {0} jz @yyy
    @DISTbits: { BPOS may be 20h since decreased soon }
    {0} movzx ebp,byte ptr [esi]
    {1-} mov ecx,edx
    {2} sub edx,(24+1)
    {@80} {0} shr edx,1Fh
    {1} add esi,edx
    {2} lea edx,[ecx+edx*08h]
    {0} shl ebp,cl
    {1} or ebx,ebp
    {2**} cmp edx,16
    {0**} jb @DISTbits
    @srcposition:
    {@91} {1} movzx ecx,ax
    {2} sar eax,10h
    {0} mov ebp,dword ptr [OFF+ecx*04h]
    {1} sub edx,ecx
    {@A0} {2} add eax,edi
    {0} and ebp,ebx
    {1} shr ebx,cl
    @copy: ...

    [ Szerkesztve ]

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #106 üzenetére

    és befele:

    @program:
    {0} movzx ecx,byte ptr [esi+00h]
    @x:
    {0**} cmp edx,ebp
    {1**} jae @init
    {2} add edx,01h
    {0**} cmp cl,[esi+edx]
    {1**} jz @x
    @init:
    { **} cmp edx,(03+01)
    { **} jae @long_jump
    { -} xor ebp,ebp
    { } mov [esp+_Q],edi
    { } mov ch,cl
    @repeat:
    {0-} mov edi,eax
    {1} and eax,(__WINDOW-1)
    {2} sub edi,ebx
    {0} mov eax,[esp+_PREV+eax*04h]
    {1**} cmp edi,-(__WINDOW)
    {2**} jbe @pre_encode { JLE = JBE for 2 negative numbers }
    {0} add edi,esi
    {1**} cmp ch,[edi+ebp]
    {2**} jnz @repeat
    {0**} cmp cl,[edi+00h]
    {1**} jnz @repeat
    {2-} xor edx,edx
    @length:
    {0**} cmp edx,[esp+...]
    {1**} jae @QQ
    {2} movzx ecx,byte ptr [esi+edx+01h]
    {0} cmp cl,[edi+edx+01h]
    {1} lea edx,[edx+01h]
    {2} jz @length
    {0} movzx ecx,byte ptr [esi+00h]
    {1} sub edi,esi
    {2} cmp edx,ebp
    {0} cmova ebp,edx
    {1} mov ch,[esi+ebp]
    {2} jbe @repeat
    {0} mov [esp+...],edi
    {1} jmp @repeat
    @QQ:
    {0} movzx ecx,byte ptr [esi+00h]
    {1} sub edi,esi
    {2} mov ebp,00000028
    {0} mov [esp+...],edi
    {1} mov edi,[esp+_Q]
    {2-} xor eax,eax
    {0**} cmp edx,???
    {1**} jz @QQQ
    {2-} mov ebp,edx
    @pre_encode:
    {0} mov edi,[esp+_Q]
    {1-} xor eax,eax
    {2*} sub ebp,03h
    {0*} jb @encode_alpha
    {1} lea edx,[ebp+03h]
    @QQQ:
    { } mov [esp+...],ebx
    { -} mov ebx,eax
    { } jz @indexed
    {---} bsr ecx,ebp
    {0*} sub ecx,02h
    {1*} jle @indexed
    {2} mov ebx,dword ptr [...+ecx*04h]
    {0-} mov eax,ecx
    {1} and ebx,ebp
    {2} shr ebp,cl
    {0} lea ebp,[ebp+ecx*04h+00h]
    @indexed:
    {0} mov ecx,dword ptr [...+ebp*04h]
    {1} mov ebp,[esp+_ZIPPED]
    {2} add al,cl
    {0} shl ebx,cl
    {1} shr ecx,10h
    {2} or ebx,ecx
    {0-} mov ecx,edi
    {1} and ecx,07h
    {2} shr edi,03h
    {0} shl ebx,cl
    {1} or bl,[edi+ebp]
    {2} add ecx,eax
    {0} mov eax,[esp+...]
    @write:
    {0} mov [edi+ebp],bl
    {1} add edi,01h
    {2} shr ebx,08h
    {0*} sub ecx,08h
    {1*} jge @write
    { } xor eax,-1
    { } mov ebp,00000005h
    { } lea edi,[edi*08h+ecx]
    { } jz @distindexed
    {---} bsr ecx,eax
    {0*} sub ecx,01h
    {1*} js @distindexed
    {2} mov ebx,dword ptr [...+ecx*04h]
    {0} add ebp,ecx
    {1} and ebx,eax
    {2} shr eax,cl
    {0} lea eax,[ecx*02h+eax]
    {1} shl ebx,05h
    @distindexed:
    {0-} mov ecx,edi
    {1} or ebx,dword ptr [...+eax*04h]
    {2} mov eax,[esp+_ZIPPED]
    {0} shr edi,03h
    {1} and ecx,07h
    {2} shl ebx,cl
    {0} add ecx,ebp
    {1} or bl,[edi+eax+00h]
    {2} mov ebp,[esp+_HASH]
    @write:
    {0} mov [edi+eax],bl
    {1} add edi,01h
    {2} shr ebx,08h
    {0*} sub ecx,08h
    {1*} jge @write
    { } add esi,edx
    { } neg edx
    { } mov ebx,[esp+...]
    { -} mov eax,ebp
    { } lea edi,[edi*08h+ecx]
    { } jmp @administration
    @encode_alpha:
    {0} mov ebp,[esp+_ZIPPED]
    {1} movzx edx,cl
    {2-} mov ecx,edi
    {1} mov edx,dword ptr [...+edx*04h]
    {0} shr edi,03h
    {2} and ecx,07h
    {0-} mov eax,edx
    {1} shr edx,10h
    {2} shl edx,cl
    {0} add cl,al
    {1} mov eax,[esp+_HASH]
    {2} or dl,[edi+ebp]
    @write:
    {0} mov [edi+ebp],dl
    {1} add edi,01h
    {2} shr edx,08h
    {0*} sub ecx,08h
    {1*} jge @write
    { } xor edx,-1
    { } mov ebp,eax
    { } add esi,01h
    { } lea edi,[edi*08h+ecx]
    @administration:
    {0} shl eax,__BITS
    {1} and eax,__LOOKUP-1
    {2} xor al,[esi+edx+03h]
    {0} mov ecx,[esp+_LAST+ebp*04h]
    {1} mov [esp+_LAST+ebp*04h],ebx
    {2-} mov ebp,ebx
    {0} add ebx,01h
    {1} and ebp,(__WINDOW-1)
    {2} mov [esp+_PREV+ebp*04h],ecx
    {1} add edx,01h
    {0-} mov ebp,eax
    {2} jnz @administration
    { } mov [esp+_HASH],eax
    { } mov ebp,[esp+_LEN]
    { } mov eax,[esp+_LAST+eax*04h]
    { *} sub ebp,ebx
    { *} jz @finalize
    { **} cmp ebp,???
    { **} jae @program
    { } mov [esp+...],ebp
    { } jmp @program
    @long_jump:

    [ Szerkesztve ]

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #108 üzenetére

    Egy program sosincs befejezve, csak abbahagyva van.

    @FIX_character:
    {@A2} {0} mov [edi],al
    {1-} mov ecx,edx
    {2} add edi,01h
    @@FIX_symbol:
    {@A9} {0} mov eax,(($1 shl ZFIX_aMAXBITS)-1)
    {1} shl ebp,cl
    {@B0} {2} xor ecx,(03h shl 03h)
    {0} and ax,bx
    {1} or edx,(03h shl 03h)
    {2} shr ecx,03h
    {0} or ebx,ebp
    {1} add esi,ecx
    @@FIX_code:
    {@C0} {2} mov ecx,dword ptr [ZFIXED_RELOC+eax*08h+_SIZE]
    {0} mov ebp,[esi]
    {1} mov eax,dword ptr [ZFIXED_RELOC+eax*08h+_CODE]
    {@D0} {2} shr ebx,cl
    {0*} sub edx,ecx
    {1*} jnc @FIX_character
    @FIX_length:
    {2} sar ecx,10h
    {0} and al,bl
    {1} sub dl,cl
    {2} shr ebx,cl
    {@FF} {0-} movzx ecx,al
    {@02} {1} sar eax,10h
    {2} jz @NXSECTION
    {0} sub eax,ecx
    {1-} movzx ecx,bl
    @FIX_distance:
    {@10} {2} sub edx,ZFIX_dBITS
    {0} mov [esp+_MOVELEN],eax
    {1} sub edi,eax
    {2} mov eax,dword ptr [ZFIXED_DISTx8+ecx*04h]
    {@20} {0-} movzx ecx,dl
    {1} shr ebx,ZFIX_dBITS
    @FIX_load:
    {2} or edx,(03h shl 03h)
    {0} shl ebp,cl
    {1} xor ecx,(03h shl 03h)
    {2} shr ecx,03h
    {@31} {0} or ebx,ebp
    {1} mov ebp,[esp+_MOVELEN]
    {2} movzx edx,dl
    {0} add esi,ecx
    {1-} mov ecx,eax
    {2} sar eax,10h
    {@41} {0} jns @FIX_movechar
    {1} jc @FIX_moveword
    {2} mov ebp,00000001h
    @FIX_movedword:
    {0} sub dl,cl
    {1} shl ebp,cl
    {2} add eax,edi
    {@50} {0} add ebp,0FFFFFFFFh
    {1} and ebp,ebx
    {2} shr ebx,cl
    {0} mov ecx,[esp+_MOVELEN]
    {1} sub eax,ebp
    @FIX_move4byte:
    {@60} {0} mov ebp,[ecx+eax+00h]
    {1} mov [edi+ecx+00h],ebp
    {2} mov ebp,[ecx+eax+04h]
    {0} mov [edi+ecx+04h],ebp
    {1*} add ecx,08h
    {@71} {2*} js @FIX_move4byte
    {0-} mov ecx,edx
    {1} mov ebp,[esi]
    {2} jmp @@FIX_symbol
    { x4 } lea eax,[edx+edx+01h]
    @FIX_movechar:
    {@60} {0} movzx eax,byte ptr [ebp+edi-01h]
    {0} imul ecx,eax
    {1-} mov eax,ebx
    @FIX_move1byte:
    {0} mov [edi+ebp+00h],ecx
    {@70} {1} mov [edi+ebp+04h],ecx
    {2*} add ebp,08h
    {0*} js @FIX_move1byte
    {1} and eax,(($1 shl ZFIX_aMAXBITS)-1)
    {2} jmp @@FIX_code
    @FIX_moveword:
    {@80} {0} add eax,edi
    @FIX_move2byte:
    {@82} {0} movzx ecx,word ptr [eax+ebp+00h]
    {1} mov [edi+ebp+00h],cx
    {2} movzx ecx,word ptr [eax+ebp+02h]
    {@8F} {0} mov [edi+ebp+02h],cx
    {@94} {1*} add ebp,04h
    {2*} js @FIX_move2byte
    {0-} mov eax,ebx
    {1} and eax,(($1 shl ZFIX_aMAXBITS)-1)
    {@A0} {2} jmp @@FIX_code

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

  • P.H.

    senior tag

    válasz P.H. #105 üzenetére

    Örömmel jelentem, hogy lassabb nem lett

    .............................

    { } movsx ebx,byte ptr [edx]
    { } xor eax,eax
    { } mov esi,ebp
    { } mov [edi+__N],ebp
    { } and esi,-8
    { } mov ecx,ebp
    @init:
    { } mov [edi+esi*08h+(00h*08h)+__K],eax
    { } mov [edi+esi*08h+(04h*08h)+__K],eax
    { } add esi,08h
    { } jnz @init
    @argument
    { } cmp ebx.00h
    { } lea eax,[ebp+ebx*04h]
    { } movsx ebx,byte ptr [edx+01h]
    { } lea edx,[edx+01h]
    { } mov [edi+eax*08h+__K],ebp
    { } cmovs eax,esi
    { } mov [edi+ecx*08h+__F],eax
    { } add ecx,04h
    { } jnz @argument
    { } mov [edi+ebp*08h-(04h*08h)+__K],esi
    { } lea edx,[ebp-04h]
    { } mov ebx,edi
    { } jmp @next0row
    @ROWS:
    { } mov [edi+__LEFT1+edx*08h+__W],esi
    @next0row:
    { } mov eax,[edi+edx*08h+(04h*08h)+__S]
    { } add edx,04h
    { } jz @@COLUMNS
    { } mov [edi+edx*08h+B],eax
    { } xor esi,esi
    { } mov [edi+edx*08h+_R],eax
    { } sub ebx,ebp
    { **} test eax,eax
    { **} jnz @@ROWS
    { } lea ecx,[ebp+04h]
    { } mov esi,[ebx+ebp]
    { } or esi,[edi+ebp*08h+__K]
    { } and ecx,-8
    @findrowmin:
    { } mov eax,[ebx+ecx]
    { } or eax,[edi+ecx*08h+__K]
    { } add ecx,08h
    { } cmp eax,ebp
    { } cmovb ebp,eax
    { } mov eax,[ebx+ecx-04h]
    { } or eax,[edi+ecx*08h-(04h*08h)+__K]
    { } cmp eax,esi
    { } cmovb esi,eax
    { **} cmp ecx,00h
    { **} jnz @findrowmin
    { } cmp ebp,esi
    { } cmovb esi,ebp
    { } mov ebp,[edi+__N]
    { } neg esi
    { } jle @@ROWS
    @@XXX:
    { } mov esi,[esp+_A]
    { } mov ecx,[esp+_I]
    { } mov dword ptr [esi+A.OPTIMUM],?
    { } mov ebx,[esi+TRESULT.NEXT]
    { } jmp ecx
    @free0col:
    { } add dword ptr [edi+__0COUNTER],-1
    { } mov [edi+__CCOLMIN],esi
    { } mov ecx,0FFFFFFFFh
    { } mov [edi+ebp*08h-(04h*08h)+__K],edx
    @0col:
    { } mov [edi+__LEFT1+edx*08h+__COLMOD],esi
    @@COLUMNS:
    { -} mov ebx,ebp
    @next0col:
    { } mov [edi+__LEFT1+edx*08h+__C],ecx
    { } mov ecx,edi+edx*08h-(04h*08h)+__K]
    { } lea eax,[edx-04h]
    { } sub eax,ebp
    { } js @@INIT0COL
    { } sub edx,04h
    { } xor ecx,-1
    { } jns @next0col
    @findcolmin:
    { } mov esi,[eax+edi]
    { } add esi,[edi+__LEFT1+ebx*08h+__U]
    { } or esi,[edi+ebx*08h+__S]
    { } jz @test0row
    { } sub eax,ebp
    { } cmp esi,ecx
    { } cmovb ecx,esi
    { } add ebx,04h
    { } jnz @findcolmin
    { } mov eax,edx
    { } lea ebx,[ebp-04h]
    { } mov esi,ecx
    { } cmp ecx,00h
    { } js @@XXX
    @seek0col:
    { } mov ecx,[edi+__LEFT1+ebx*08h+(04h*08h)+__W]
    { } sub eax,ebp
    { } add ebx,04h
    { } jz @free0col
    { } add ecx,[eax+edi]
    { **} cmp ecx,esi
    { **} jnz @seek0col
    @test0row:
    { } mov ecx,[edi+ebx*08h+B]
    { **} test ecx,ecx
    { **} js @seek0col
    { } mov [edi+ebx*08h+B],edx
    { } mov [edi+edx*08h+__K],ebx
    { } jmp @0col
    @@INIT0COL:
    { } lea eax,[edi+ecx]
    { } mov [edi+__L],ecx
    { } neg ebp
    { } sal ecx,10h
    { } jnz @init2col
    { -} xor esi,esi
    { } jmp @@FINISHED
    @@5TH_STEP:
    { -} mov edx,esi
    { } movsx esi,si
    { } sar eax,10h
    @5TH_STEP:
    { } movsx ecx,byte ptr [edi+__LEFT1+ebx*08h+__SIGN+__C]
    { } and ecx,edx
    { } add [edi+__LEFT1+ebx*08h+__COLMOD],ecx
    { } movsx ecx,byte ptr [edi+ebx*08h+__SIGN+_R]
    { } and ecx,edx
    { } add [edi+__LEFT1+ebx*08h+__W],ecx
    { } add ebx,04h
    { } jnz @5TH_STEP
    { } mov edx,es:[edi+esi*08h+B]
    { } db $8B,$8C,$3B,__L,?,?,?
    { **} test edx,edx
    { **} jz @@4TH_STEP
    { } add dword ptr [edi+__PN],-1
    { } mov [edi+esi*08h+_R],eax
    { } mov [edi+__LEFT1+edx*08h+__C],esi
    { } cmp edx,ecx
    { } cmovb ecx,edx
    { } sub ebx,ebp
    { } mov [edi+__L],ecx
    { } jmp @@9ND_STEP
    @fast6forward:
    { } mov esi,[edi+__LEFT1+ebx*08h+(04h*08h)+__W]
    { } add ebx,04h
    { } jz @pass8col
    { } sal ecx,10h
    { } jmp @loop
    @pass8col:
    { } mov eax,[edi+__N]
    { } sub ebx,ebp
    { } mov [edi+__LEFT1+ecx*08h+__C],eax
    @next20col:
    { } add ecx,04h
    { } jz @@5TH_STEP { clears ECX register
    { **} cmp [edi+__LEFT1+ecx*08h+__C],eax
    {0**} jbe @next20col
    @@8ND_STEP:
    { } mov esi,[edi+__LEFT1+ecx*08h+__COLMOD]
    { } lea eax,[edi+ecx]
    { } mov [edi+__CCOL],esi
    { } imul ecx,00010000h
    @init2col:
    { } add eax,ebp
    { } mov esi,[edi+ebx*08h+__W]
    @loop:
    { } sub esi,[edi+__COLMIN]
    { } add esi,[eax]
    { } lea eax,[eax+ebp]
    { } jo @over6flow
    { } or esi,[edi+ebx*08h+_R]
    { } jz @@11D_STEP
    { } cmp esi,edx
    { } cmovb edx,esi
    { } cmovb cx,bx
    @over6flow:
    { } mov esi,[edi+__LEFT1+ebx*08h+(04h*08h)+__W]
    { } add ebx,04h
    { } jnz @loop
    { -} mov eax,ecx
    { } sar ecx,10h
    { } cmovc esi,eax
    { } mov [edi+__MC],esi
    { } jmp @pass8col
    @@11D_STEP:
    { -} mov esi,ecx
    { } sar ecx,10h
    { } cmovnc esi,[edi+__M]
    { } mov [edi+__MC],esi
    { } mov esi,[edi+ebx*08h+B]
    { **} test esi,esi
    { **} jz @4TH_STEP
    { } mov [edi+ebx*08h+_R],ecx
    { } mov [edi+__LEFT1+esi*08h+__C],-1
    { **} cmp word ptr [edi+__MC],bx
    { **} jz @re2start
    { **} cmp esi,ecx
    { **} jae @fast6forward
    { } mov ecx,esi
    { } xor ebx,ebx
    { } mov eax,[edi+__L]
    { } sub ebx,ebp
    { } cmp esi,eax
    { } cmovb eax,esi
    { } mov [edi+__L],eax
    { } jmp @@7ND_STEP
    @re2start:
    { } mov ecx,[edi+__L]
    { } xor ebx,ebx
    { } add dword ptr [edi+__PN],-1
    { } mov edx,esi
    { } cmp esi,ecx
    { } cmovb ecx,esi
    { } sub ebx,ebp
    { } mov [edi+__L],ecx
    { } jmp @@6ND_STEP
    @@4TH_STEP:
    { } mov ecx,eax
    { } mov ebx,esi
    @4TH_STEP:
    { } mov [edi+ebx*08h+BB],ecx
    { } mov edx,[edi+ecx*08h+__K]
    { } mov [edi+ecx*08h+__K],ebx
    { } mov ebx,edx
    { } mov ecx,[edi+edx*08h+_R]
    { } sub edx,ebp
    { } jnc @4TH_STEP
    { } xor esi,esi
    { } mov ebx,edx
    { } sub dword ptr [edi+__0COUNTER],-1
    { } jz @@FINISHED
    @@1ST_STEP:
    { } mov eax,[edi+esi*08h-(04h*08h)+__K]
    { } xor eax,-1
    { } mov [edi+__LEFT1+esi*08h-(04h*08h)+__C],eax
    { } lea esi,[esi-04h]
    { } mov eax,[edi+esi*08h+__S]
    { } cmovs ecx,esi
    { } mov [edi+esi*08h+_R],eax
    { **} cmp edx,esi
    { **} jnz @@1ST_STEP
    { } nop
    { } mov [edi+__L],ecx
    { } jmp @@5ND_STEP

    @@FINISHED:
    { } mov eax,edi
    { } mov ecx,[esp+_KIMENET]
    { } mov ebp,edx
    @@results:
    { } mov ebx,[edi+edx*08h+__B]
    { } sub eax,ebp
    { } add esi,[eax+ebx]
    { } sub ebx,ebp
    { } shr ebx,02h
    { } mov [ecx],bl
    { } add ecx,01h
    { } add edx,04h
    { } jnz @@results
    (CODE)

    [ Szerkesztve ]

    Arguing on the Internet is like running in the Special Olympics. Even if you win, you are still ... ˙˙˙ Real Eyes Realize Real Lies ˙˙˙

Aktív témák