Aktív témák
-
P.H.
senior tag
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 órajelEz 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
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
retA "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
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
@@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
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
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
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.1Mivel 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-benJelen 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
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
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
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
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ítArguing 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
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
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
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
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 @resultsKis á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 lehetElső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-enA 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
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
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
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],ecxArguing 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
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
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átrixCore-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.7Ez 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
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
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_colA 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
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
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
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 fő 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
é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
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_codeArguing 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
Ö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
- Gigabyte B450M DS3H + Ryzen 7 2700X alaplap+processzor (nem ad képet)
- Eladó gamer PC (Ryzen 5 7600X/16GB DDR5/512GB SSD/RTX 4070 Super)
- Eladó gamer PC (i5-6500/16GB DDR4/120GB SSD+320GB HDD/GTX 1050Ti)
- Eladó új gamer PC (i5-12400F/16GB DDR4/512GB SSD/RX 7600)
- Eladó gamer PC (i5-8500/16GB DDR4/256GB SSD+500GB HDD/GTX 1650 4GB)