Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Verwijderd
1
2
3
4
5
6
| Osiris : 3624811us (millisec) Curry : 799488us (millisec) Beelzebubu : 820976us (millisec) Sponz : 1587067us (millisec) Oisyn : 911884us (millisec) oisyn_asm : 107143us (millisec) |
P3/800 wederom..
maar ik blijf me nog steeds verbazen over het feit dat zo'n simpel asm functietje 7x zo snel is als de op-een-na-snelste
na ja met deze compiler dan
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Verwijderd
Mja hij kan wel inline asm maar gaat over z'n nek van die lea instructie.Op donderdag 30 augustus 2001 19:06 schreef OiSyN het volgende:
t ziet er al beter uit ja... maar een compiler die geen inline asm kan is nog steeds een CRAP-compiler
Ik dacht dat het voor snelheid niet zoveel meer uitmaakte.
Maar blijkbaar nog ruimschoots genoeg om je tijd eruit te halen..
Atari Terminator AI - LegoBlockX3 = ᒢᐩᐩ.ᒡᒢᑊᒻᒻᓫᔿ.ᣳᣝᐤᣜᣳ.ᐪᓫᣗᔿᑊᣕᣔᐪᐤᣗ.T008ᖟ
Verwijderd
/me is trots dat hij nog steeds de snelste C-methode isOp donderdag 30 augustus 2001 18:49 schreef Yarvieh het volgende:
code:
1 2 3 4 5 6 7 Intel MicroSoft VectorC Osiris : 3609ms 5532ms 2016ms Curry : 453ms 500ms 609ms Beelzebubu : 422ms 343ms 578ms Sponz : 937ms 907ms 1047ms Oisyn : 579ms 500ms 625ms OiSyN_Asm : 156ms 93ms *
ik zal zometeen die AT&T implementatie dinges van jou eens proberen, ik kreeg de normale met __asm__ niet gecompilet... Zal wel aan mij liggen, ik ben een ramp met asm
Atari Terminator AI - LegoBlockX3 = ᒢᐩᐩ.ᒡᒢᑊᒻᒻᓫᔿ.ᣳᣝᐤᣜᣳ.ᐪᓫᣗᔿᑊᣕᣔᐪᐤᣗ.T008ᖟ
Wat voor voordeel heeft die dan als alles al in de cache zit?Op donderdag 30 augustus 2001 18:32 schreef OiSyN het volgende:
[..]
align is WEL belangrijk, zelfs met cache
en idd, zoals Yarvieh al zei, die dec heb ik daar gezet omdat die jz anders niet werkte
En wat als je die inc (was toch geen dec) nog eentje naar boven zet?
Verwijderd
Inc reset je Zeroflag dus het resultaat van je cmp gaat verloren dan.Op donderdag 30 augustus 2001 21:17 schreef OlafvdSpek het volgende:
En wat als je die inc (was toch geen dec) nog eentje naar boven zet?
ow wacht kwartje valt nu pas , ff proberen
Beelzebubu : 561msOp donderdag 30 augustus 2001 19:12 schreef OiSyN het volgende:
ah kijk eens aan
maar ik blijf me nog steeds verbazen over het feit dat zo'n simpel asm functietje 7x zo snel is als de op-een-na-snelste
na ja met deze compiler dan, maar met die van microsoft was het nog altijd 3.5x zo snel
Oisyn : 690ms
OisynAsm : 504ms
Dat vind ik toch niet zo'n groot verschil, al had ik wel verwacht dat de optimizer betere code zou zijn genereren dan jie.
Verwijderd
Okay, als je die inc nog 1 naar boven zit , zit ie die mov dwars waardoor ie naar de ~110ms schiet..Op donderdag 30 augustus 2001 21:17 schreef OlafvdSpek het volgende:
En wat als je die inc (was toch geen dec) nog eentje naar boven zet?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
| void Marcus() { char *msg = "Blablabla"; _asm { mov edx, [msg] sub edx, 4 loop1: add edx, 4 mov eax, dword ptr [edx] mov ebx, eax mov ecx, eax //cbyte3: and ebx, 0x0FF000000 test ebx, ebx jz end cmp ebx, 0x061000000 jz rbyte3 cbyte2: mov ebx, eax and ebx, 0x00FF0000 test ebx, ebx jz end cmp ebx, 0x00610000 jz rbyte2 cbyte1: mov ebx, eax test ah, ah jz end cmp ah, 0x061 jz rbyte1 cbyte0: test al, al jz end cmp al, 0x061 jz rbyte0 check: cmp eax, ecx jz loop1 mov [edx], eax jmp loop1 rbyte3: add eax, 0x02000000 jmp cbyte2 rbyte2: add eax, 0x00020000 jmp cbyte1 rbyte1: add eax, 0x00000200 jmp cbyte0 rbyte0: add eax, 0x00000002 jmp check end: } } |
pfff... wat een gedoe zeg, voor zo'n simpele functie
ik heb sys/time.h en sys/dieandere.h niet, dus ik heb het zelf niet vergeleken met de andere.
1
2
3
4
5
6
7
8
9
10
| // Hulpmacro #define Test(p_Method) \ QueryPerformanceCounter(&qwstart); \ for(i = 0; i != c_Iterations; i++) \ p_Method(); \ QueryPerformanceCounter(&qwend); \ start = (double)(qwstart.QuadPart / freq); \ end = (double)(qwend.QuadPart / freq); \ printf("%10s : %f ms\n", #p_Method, \ (end-start)*1000) |
Resultaat:
1
2
3
4
| Marcus : 238.629211 ms OiSyN : 293.651847 ms Curry : 409.611277 ms Beelzebubu : 396.126044 ms |
De mijne is iets sneller van die van OiSyN
een dword inlezen is idd sneller, maar hij leest het toch wel in de cache in, dus tegen de tijd dat je de andere bytes nodig hebt dan kan ie ze er zo uit halen.
en olaf: een inc verandert ook de flags
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Verwijderd
1
2
3
4
5
6
7
| Osiris : 5594ms Sponz : 890ms Oisyn : 531ms Curry : 500ms Beelzebubu : 344ms Marcus_Asm : 297ms OiSyN_Asm : 94ms |
Meer dan 3x zo langzaam als OiSyN z'n versie maar nog altijd sneller dan de C versies
- overflow flag
- sign flag
- zero flag
- auxilary flag
- parity flag
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Verwijderd
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Toch wel een verschil:Op donderdag 30 augustus 2001 23:19 schreef Yarvieh het volgende:
code:
1 2 3 4 5 6 7 Osiris : 5594ms Sponz : 890ms Oisyn : 531ms Curry : 500ms Beelzebubu : 344ms Marcus_Asm : 297ms OiSyN_Asm : 94ms
Meer dan 3x zo langzaam als OiSyN z'n versie maar nog altijd sneller dan de C versies
1
2
3
4
| Marcus : 238.629211 ms OiSyN : 293.651847 ms Curry : 409.611277 ms Beelzebubu : 396.126044 ms |
Vaag! Bij mij is ie dus sneller !
Gecompiled met MSVC++ 5.0, Optimization: Maximize Speed, Inline function expansion: Any Suitable.
mmja okee maar waarom zei ie er dan bij: 'het is toch geen dec?'Op donderdag 30 augustus 2001 23:26 schreef Yarvieh het volgende:
Olaf bedoelde ook die inc nog een instructie omhoog, (dan komt ie onder de mov terrecht) want dan zit ie die jz niet meer dwars (maar dan zit ie die mov weer dwars)
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
1
2
3
4
5
6
7
8
9
10
11
| loop1: add edx, 4 mov eax, dword ptr [edx] mov ebx, eax // mov ecx, eax ... check: // cmp eax, ecx // jz loop1 mov [edx], eax jmp loop1 |
zo is ie nog iets sneller
wheeeheheheheee ik znap mOp donderdag 30 augustus 2001 23:30 schreef Yarvieh het volgende:
lees je berichtje van 18:32 nog es terug
tiepvaudje van mij
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Verwijderd
1
2
3
4
5
6
7
| Osiris : 5563.573474 ms Sponz : 899.178761 ms Oisyn : 536.955267 ms Curry : 504.973432 ms Beelzebubu : 359.470699 ms Marcus : 303.102538 ms OiSyN_Asm : 51.321776 ms |
als je de asm code van beelzebub eens uitdraait, dan kunnen we vergelijken wat er nou precies aan het handje is...
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Maar niet heusOp donderdag 30 augustus 2001 23:39 schreef OiSyN het volgende:
al met al toch weer 114 (met deze erbij) ontopic posts over een simpel onderwerp als dit
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Ja, maar het ging om C++. Maakt niet uit hoor, het blijft wel grappig dit.Op donderdag 30 augustus 2001 23:51 schreef OiSyN het volgende:
hoezo maar niet heus, het gaat toch nog steeds over dat char-wijzig-proggie van osiris? zijn naam wordt zelfs nog om de zoveel posts genoemd... kun je nagaan
/edit weer es wat anders dan die stinkende php topics
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| void OiSyN_asm1() { char * Msg = "Blablabla"; _asm { mov edx, Msg loopstart: mov al, [edx] or al, al jz end inc edx cmp al, 'a' jne loopstart mov byte ptr [edx - 1], 'c' jmp loopstart end: } } |
ipv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| void OiSyN_asm2() { char msg[] = "Blablabla"; __asm { lea edx,[esp-0Ch] loopstart: mov al, [edx] or al, al jz end inc edx cmp al, 'a' jne loopstart mov byte ptr [edx - 1], 'c' jmp loopstart end: } } |
Met als resultaat:
1
2
3
4
5
| Marcus_asm : 406.916522 ms OiSyN_asm1 : 437.635789 ms OiSyN_asm2 : 79.910994 ms Curry : 709.925982 ms Beelzebubu : 710.010909 ms |
Blijkbaar is de lea instructie heel wat sneller dan mov
anyway, da was vroeger zo, t zal nu toch wel niet meer uitmaken met de verbeterde branch-prediction tegenwoordig
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Verwijderd
Op donderdag 30 augustus 2001 23:46 schreef OiSyN het volgende:
zie je, ik zei toch 7x zo snel als de snelste c-versie
als je de asm code van beelzebub eens uitdraait, dan kunnen we vergelijken wat er nou precies aan het handje is...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
| PUBLIC ?Beelzebubu@@YAXXZ ; Beelzebubu _DATA SEGMENT ORG $+2 $SG42330 DB 'Blablabla', 00H _DATA ENDS _TEXT SEGMENT _Msg$ = -12 ?Beelzebubu@@YAXXZ PROC NEAR ; Beelzebubu ; 55 : { push ebp mov ebp, esp sub esp, 12 ; 0000000cH ; 56 : int i; ; 57 : char Msg[] = "Blablabla"; mov eax, DWORD PTR $SG42330 mov ecx, DWORD PTR $SG42330+4 mov dx, WORD PTR $SG42330+8 mov DWORD PTR _Msg$[ebp], eax ; 58 : for(i=0;Msg[i];i++) test al, al mov DWORD PTR _Msg$[ebp+4], ecx mov WORD PTR _Msg$[ebp+8], dx je SHORT $L42333 ; 56 : int i; ; 57 : char Msg[] = "Blablabla"; lea eax, DWORD PTR _Msg$[ebp] $L42331: ; 59 : if(Msg[i]=='a') cmp BYTE PTR [eax], 97 ; 00000061H jne SHORT $L42332 ; 60 : Msg[i]='c'; mov BYTE PTR [eax], 99 ; 00000063H $L42332: ; 58 : for(i=0;Msg[i];i++) mov cl, BYTE PTR [eax+1] inc eax test cl, cl jne SHORT $L42331 $L42333: ; 61 : } mov esp, ebp pop ebp ret 0 ?Beelzebubu@@YAXXZ ENDP ; Beelzebubu |
Op donderdag 30 augustus 2001 23:53 schreef marcusk het volgende:
Met als resultaat:
code:
1 2 3 4 5 Marcus_asm : 406.916522 ms OiSyN_asm1 : 437.635789 ms OiSyN_asm2 : 79.910994 ms Curry : 709.925982 ms Beelzebubu : 710.010909 ms
Blijkbaar is de lea instructie heel wat sneller dan mov
Dat kan nooit, ik denk dat er andere factoren bij komen kijken... toch wazig...
ow ik zie het al, dat moet
1
| lea edx, [esp - 8] |
zijn. daarom stopt ie natuurlijk eerder, omdat er voor de string op de stack een 0 staat (na 2 of 3 bytes welteverstaan, in het returnadres)
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
is dat de geoptimizede? hij gebruikt die index als variabeleOp donderdag 30 augustus 2001 23:56 schreef Yarvieh een asm uitdraai, volgens mij zonder optimalizatie
.edit: oh nee ik kijk verkeerd.... wel een wazige routine hoor
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Je speelt dus vals ! Ja, zo kan ik het ook !ow ik zie het al, dat moet
code:
1 lea edx, [esp - 8]
zijn. daarom stopt ie natuurlijk eerder, omdat er voor de string op de stack een 0 staat (na 2 of 3 bytes welteverstaan, in het returnadres)
Maargoed... dit is het resultaat nadat ik er lea eax, [esp-8] van gemaakt heb:
1
2
3
4
5
| Marcus_asm : 408.052979 ms OiSyN_asm1 : 88.824418 ms OiSyN_asm2 : 437.228475 ms Curry : 710.279658 ms Beelzebubu : 710.022363 ms |
Niet veel verschil dus
Verwijderd
Helaas? als ik een breakpoint neer gooi op die 1e mov al,[edx] wijst ie netjes naar een Hoofdletterje B.Op vrijdag 31 augustus 2001 00:00 schreef OiSyN het volgende:
[..]
ow ik zie het al, dat moet lea edx, [esp - 8]
zijn. daarom stopt ie natuurlijk eerder, omdat er voor de string op de stack een 0 staat (na 2 of 3 bytes welteverstaan, in het returnadres)
source gecompileerd met cl /c /FAs /Fa /Og Test.cpp (kon zo snel niet vinden hoe je 'm asm uit liet poepen dus maar het 1e commando gecutpaste wat ik tegen kwam)
heej heej heej iemand ANDERS heeft er lea van gemaakt hoor! Ik had er oorspronkelijk "mov edx, Msg" staan, maar dat compilede niet volgens iemandOp vrijdag 31 augustus 2001 00:05 schreef marcusk het volgende:
[..]
Je speelt dus vals ! Ja, zo kan ik het ook !
Maargoed... dit is het resultaat nadat ik er lea eax, [esp-8] van gemaakt heb:
code:
1 2 3 4 5 Marcus_asm : 408.052979 ms OiSyN_asm1 : 88.824418 ms OiSyN_asm2 : 437.228475 ms Curry : 710.279658 ms Beelzebubu : 710.022363 ms
Niet veel verschil dus
.edit: en maak er voor de grap eens "lea edx, [ebp + 4]" van
.edit2: nee wacht, dit is een betere
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| void OiSyN_asm2() { char msg[] = "Blablabla"; __asm { mov edx, ebp nop loopstart: mov al, [edx + 4] or al, al jz end inc edx cmp al, 'a' jne loopstart mov byte ptr [edx + 3], 'c' jmp loopstart end: } } |
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Ik heb het nu dus gefixed, en dit is het resultaat:
1
2
3
4
5
| Marcus_asm : 220.990936 ms OiSyN_asm1 : 281.146626 ms OiSyN_asm2 : 78.056289 ms Curry : 403.181689 ms Beelzebubu : 402.810134 ms |
OiSyN_asm1 is met "char * Msg = TEST" en "mov edx, Msg", en OiSyN_asm2 met "mov edx, ebp". Ik heb #define TEST "Blablabla" gedaan.
Hoe kan dat grote verschil tussen OiSyN_asm1 en OiSyN_asm2 nou verklaard worden? En hoe weet je dat het adres van Msg in ebp staat?
Dat had ik eerst ook. Toen heb ik van "char Msg[] = TEST" "char * Msg = TEST" gemaakt, en dan compilede wel.Ik had er oorspronkelijk "mov edx, Msg" staan, maar dat compilede niet volgens iemand
Verwijderd
const int c_Iterations = 15000 * 1000;
ebp+4 460ms
esp-0c 151ms
En da's lekkerOp donderdag 30 augustus 2001 23:53 schreef Sponz het volgende:
/edit weer es wat anders dan die stinkende php topics

Sowieso, ik vind dit gewoon teringgaaf. Ik word op m'n werk voor hacker uitgemaakt omdat C++ functies spontaan 3 keer sneller worden zodra je mij er een kwartier mee alleen laat (en niemand snapt er daarna nog een kont van maar het werkt wel, en snelllll
Overigens, het is een jaar of 6 geleden dat ik op de Amiga nog assembler programmeerde (laatste regel asm die ik ooit gedaan heb), maar ik wil nog wel een poginkje op MC680x0 assembler doen uit het blote hoofd:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| Exchange: lea Message, a0 Loop1: cmp.b #'a', (a0) bne Loop2 move.b #'c', (a0)+ bra Loop1 Loop2: tst.b (a0)+ bne Loop1 rts Message: dc.b "Blablabla", 0 |
Kan
a) Iemand me vertellen hoeveel hout dit snijdt?
b) Iemand me vertellen waarom Intel in vergelijking met dit soort asm zo'n BAGGERINSTRUCTIESET heeft waardoor ik er nooit toe ben gekomen het te leren?
je moet helemaal niet werken met esp, omdat de string op de stack gealloceerd wordt... dus je moet [esp - lengte van de string + 1] nemen.Op vrijdag 31 augustus 2001 00:19 schreef Yarvieh het volgende:
Ik heb geen idee waarom, maar de esp variant is *VEEL* sneller dan de ebp variant. ik heb het aantal iteraties een beetje omhoog geschroeft (Getallen werden me een beetje *TE* klein)
const int c_Iterations = 15000 * 1000;
ebp+4 460ms
esp-0c 151ms
Maar [ebp - 4] is wel goed, aangezien bij [ebp - 4] de lokale variabelen beginnen
dus moest het bij mijn 2e func ook zijn: ebp min 4
de functie van net wordt dan ook
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| void OiSyN_asm2() { char msg[] = "Blablabla"; __asm { mov edx, ebp nop loopstart: mov al, [edx - 4] or al, al jz end inc edx cmp al, 'a' jne loopstart mov byte ptr [edx - 5], 'c' jmp loopstart end: } } |
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
a) waarschijnlijk niet genoeg planken voor een heel huis, maar ik weet ook niet hoeveel dan welOp vrijdag 31 augustus 2001 00:50 schreef curry684 het volgende:
[..]
a) Iemand me vertellen hoeveel hout dit snijdt?
b) Iemand me vertellen waarom Intel in vergelijking met dit soort asm zo'n BAGGERINSTRUCTIESET heeft waardoor ik er nooit toe ben gekomen het te leren?
b) waarom is de instructieset van intel bagger
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Verwijderd
Euh 't begint een beetje laat te worden maar staan op ebp(+/-)4 niet de parameters ipv de lokale variabelen?Op vrijdag 31 augustus 2001 00:55 schreef OiSyN het volgende:
Maar [ebp - 4] is wel goed, aangezien bij [ebp - 4] de lokale variabelen beginnen
Op vrijdag 31 augustus 2001 01:14 schreef Yarvieh het volgende:
[..]
Euh 't begint een beetje laat te worden maar staan op ebp(+/-)4 niet de parameters ipv de lokale variabelen?
idd
parameters van de functies beginnen vanaf [ebp + 8]
lokale variabelen beginnen vanaf [ebp - 4]
[ebp] bevat de vorige waarde van ebp en
[ebp + 4] bevat de return positie
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Ik heb hier ondertussen m'n MC68000 bijbel teruggevonden, en tot de zolder haalt ie het welOp vrijdag 31 augustus 2001 01:03 schreef OiSyN het volgende:
a) waarschijnlijk niet genoeg planken voor een heel huis, maar ik weet ook niet hoeveel dan wel
Alleen deze instructie al die ik gebruikte:b) waarom is de instructieset van intel baggerik vind ze behoorlijk vergelijkbaar, alleen de naamgeving en de syntax is iets anders, maar dat hoort verder niet bij de instructieset
move.b #'c', (a0)+
Dat deed de MC68000 7.14Mhz in 1978 al, en ik zie jullie hier met Athlon 1Ghz nog in afzonderlijke instructies moeilijk doen met INC op het adresregister?!?
Tevens, met instructieset bedoelde ik in het algemeen 'de assembleromgeving'. De MC68000 had 8 32-bits dataregisters (D0-D7) en 8 32-bits adresregisters waarvan A7 de stack was. Als je een interrupt kreeg kon je het volgende doen:
1
2
3
4
| movem.l (d0-d7/a0-a6), -(sp) // Code movem.l (sp)+, (d0-d7/a0-a6) rts |
32 bytes geheugen kopieren was op de 68000 als volgt:
1
2
3
4
| move.w #7, d0 Loop: move.l (a0)+, (a1)+ dbra d0, Loop |
Waarom kan dit op een CPU uit het jaar 2001 nog steeds niet in 3 instructies blijkbaar? Waarom heeft diezelfde CPU nog steeds zo weinig data/adresregisters dat je constant in langzaam geheugen moet schrijven? Waarom is die instructieset (voor zover ik 'm hier gebruikt zie) nog steeds uit het jaar 1955 van toen de eerste chip op de markt kwam?
Verwijderd
1
2
| push ebp mov ebp, esp |
dit als eerste genereerd voor een functie...
ik zie 't nie meer zo helder, (had ook al de halve avond tegen interfaces aan zitten trappen die 't vertikte te marshallen) ik zie overal pointers vliegen momenteel, ik haak af , morgen nieuwe dag en zijn we allemaal weer fris en fruitig
en dan komt amd met de hammer: het aantal registers is verdubbeld, en dat is goed, MAAR HOE KOMT HET DAT DE ITANIUM ER WEL 320 HEEFT ?!?!?!?!?!!?
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
ja en daar gaat het toch ook om? esp kun je in principe niet gebruiken, omdat de string "blablabal\0" OOK op de stack staatOp vrijdag 31 augustus 2001 01:20 schreef Yarvieh het volgende:
Je haalt esp en ebp door elkaar. je hebt *inprinciepe* wel gelijk maar dat is omdat 99.99% van de compilers
code:
1 2 push ebp mov ebp, esp
dit als eerste genereerd voor een functie...
want er gebeurt dit:
1
2
3
4
5
6
7
8
9
10
| push ebp mov ebp, esp sub esp, BYTES_VAN_ALLE_LOKALE_VARIABELEN_BIJ_ELKAAR mov [ebp - 4 - strlen ("blablabla") - 1], "blablabla\0" .... mov esp, ebp pop ebp ret |
ho nou zie ik ook ineens waarom [ebp - 4] ook niet gaat werken, daat staat het eind van de string, niet het begin
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
mietje! nep-coder!Op vrijdag 31 augustus 2001 01:20 schreef Yarvieh het volgende:ik zie 't nie meer zo helder, (had ook al de halve avond tegen interfaces aan zitten trappen die 't vertikte te marshallen) ik zie overal pointers vliegen momenteel, ik haak af , morgen nieuwe dag en zijn we allemaal weer fris en fruitig
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Verwijderd
Geen idee wat die instructie doet maar het lijkt een beetje op een intel lodsb of stosb ofzo?Op vrijdag 31 augustus 2001 01:18 schreef curry684 het volgende:
Alleen deze instructie al die ik gebruikte:
move.b #'c', (a0)+
Dat deed de MC68000 7.14Mhz in 1978 al, en ik zie jullie hier met Athlon 1Ghz nog in afzonderlijke instructies moeilijk doen met INC op het adresregister?!?
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
1
| move.l 16(a6, d5.w), d2 |
Geniaal spul toch
Dit ging dus over: move.b #'c', (a0)+Op vrijdag 31 augustus 2001 01:28 schreef Yarvieh het volgende:
Geen idee wat die instructie doet maar het lijkt een beetje op een intel lodsb of stosb ofzo?
Schrijf een byte-formaat 'c'-karakter weg op het adres waar a0 naar wijst, en verhoog naderhand a0 met het formaat van de operatie (byte in dit geval, kan ook met word of long). In C: *(BytePointer++) = 'c';
DRIE HONDERD TWINTIG?!?!?!?!?!?Op vrijdag 31 augustus 2001 01:21 schreef OiSyN het volgende:
en dan komt amd met de hammer: het aantal registers is verdubbeld, en dat is goed, MAAR HOE KOMT HET DAT DE ITANIUM ER WEL 320 HEEFT ?!?!?!?!?!!?
Zeg me dat dat een grapje is?
Dat is toch niet meer te onderhouden, een hele f**king cache als dataregisters? Hoe groot worden die instructies wel niet?
ja totaal dan, je kunt ze niet allemaal overal voor gebruiken, maar je hebt iig al 128 (!!!!) generieke data registers... wacht effe ik pak de spec er effe bijOp vrijdag 31 augustus 2001 01:49 schreef curry684 het volgende:
[..]
DRIE HONDERD TWINTIG?!?!?!?!?!?![]()
![]()
Zeg me dat dat een grapje is?
Dat is toch niet meer te onderhouden, een hele f**king cache als dataregisters? Hoe groot worden die instructies wel niet?
.edit: oh, het is dus geen grapje btw
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
ftp://download.intel.com/design/itanium/downloads/24963401.pdf
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Uh oh dit wordt echt gevaarlijk:
Dus waar gaan we het over hebben om 2 uur 's nachts...Over offtopic-gedrag kunnen wij ook simpel zijn: probeer het gewoon gezellig te houden, een keer offtopic praten kan best (heel de dag lullen over variabelen is ook niet echt alles)
320 registers waar je ALLEMAAL VARIABELEN IN KUNT STOPPEN!!!
AAAAAAAAAARGHHHHH!!!!!!!!!




(ps. nee ACM nog even geeeeeeen slotje, het is nog steeds interessant en in de buurt van het topic
UPDATE:
256 general and floating point registers with rotating registers (
hmmm dit document gaat meer over de chip zelf, dan over de instructies enzo...
maar goed, je had dus 128 64-bits registers, en 128 floating point registers
Wat ze bedoelen met rotating registers begrijp ik niet helemaal...
Maar er was ook iets vaags over geen multithreading support ofzo... lijkt me ook logisch aangezien je niet 256 * 64-bits registers = 2 kilobyte aan data op de stack gaat pleuren elke keer als je van thread switched
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Wat raar. Het lijkt me dat die mov en inc parallel uitgevoerd kunnen worden.Op donderdag 30 augustus 2001 21:25 schreef Yarvieh het volgende:
[..]
Okay, als je die inc nog 1 naar boven zit , zit ie die mov dwars waardoor ie naar de ~110ms schiet..
Verwijderd
nou nee? ze gebruiken het zelfde register dus zullen nooit parralel uit gevoerd worden..Op vrijdag 31 augustus 2001 09:30 schreef OlafvdSpek het volgende:
[..]
Wat raar. Het lijkt me dat die mov en inc parallel uitgevoerd kunnen worden.
Verwijderd
Euhm, oisyn.....................
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| [30 Aug - rbultje@tux rbultje]# g++ snelheid.c -o snelheid [30 Aug - rbultje@tux rbultje]# ./snelheid Blcblcblc - Osiris : 5020087us (millisec) Blcblcblc - Curry : 2334306us (millisec) Blcblcblc - Beelzebubu : 2352219us (millisec) Blcblcblc - Sponz : 3261743us (millisec) Blcblcblc - Oisyn : 2195206us (millisec) blablabla - oisyn_asm : 902367us (millisec) [30 Aug - rbultje@tux rbultje]# g++ -O2 snelheid.c -o snelheid [30 Aug - rbultje@tux rbultje]# ./snelheid Blcblcblc - Osiris : 11897042us (millisec) Blcblcblc - Curry : 1230205us (millisec) Blcblcblc - Beelzebubu : 1436798us (millisec) Blcblcblc - Sponz : 2692134us (millisec) Blcblcblc - Oisyn : 1921786us (millisec) oisyn_asm : 712611us (millisec) [30 Aug - rbultje@tux rbultje]# |
Die code van jou werkt van geen kant, geen wonder dattie zo snel is
Bij hogere optimalisatie weigerde hij overigens uberhaupt te compileren...... Duseuh, die asm-implementatie van oisyn heeft nog wat werk nodig
Waarom niet?Op vrijdag 31 augustus 2001 11:37 schreef Yarvieh het volgende:
[..]
nou nee? ze gebruiken het zelfde register dus zullen nooit parralel uit gevoerd worden..
Het is toch geen read after write dependency? Dat register kan gewoon gelezen worden op het moment dat de instructies de data nodig hebben.
cool, dan wordt ie nog weer iets sneller :Op vrijdag 31 augustus 2001 09:40 schreef OlafvdSpek het volgende:
code:
1 2 and ebx, 0x0FF000000 test ebx, ebx
Die test is niet nodig, de and zet de flags zelf al.
1
2
3
4
5
| Marcus_asm | Blcblcblc | 309.970401 ms OiSyN_asm1 | Blcblcblc | 398.973613 ms OiSyN_asm2 | Blablabla | 219.241831 ms Curry | Blcblcblc | 695.252609 ms Beelzebubu | Blcblcblc | 824.309235 ms |
OiSyN_asm2 werkt hier idd niet goed
Maar dat komt natuurlijk omdat de string die hier gebruikt wordt een globale ipv locale var is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| const int c_Iterations = 5000 * 1000; #define TEST "Blablabla" // Hulpmacro #define Test(p_Method) \ strcpy(Msg, TEST); \ QueryPerformanceCounter(&qwstart); \ for(i = 0; i != c_Iterations; i++) \ p_Method(); \ QueryPerformanceCounter(&qwend); \ start = (double)(qwstart.QuadPart / freq); \ end = (double)(qwend.QuadPart / freq); \ printf("%10s | %10s | %f ms\n", #p_Method, \ Msg, (end-start)*1000) char * Msg; |
Er zat nog een bug in mn asm, waardoor ie de laatste a niet verving door e (om een één of andere reden begon ik bij byte3 te checken ipv byte0). Dit is de nieuwe (en ook nog iets snellere) versie:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
| _asm { mov edx, [Msg] loop1: mov eax, dword ptr [edx] //cbyte0: test al, al jz end cmp al, 0x061 jz rbyte0 cbyte1: test ah, ah jz end cmp ah, 0x061 jz rbyte1 cbyte2: mov ebx, eax and ebx, 0x00FF0000 jz end cmp ebx, 0x00610000 jz rbyte2 cbyte3: mov ebx, eax and ebx, 0x0FF000000 jz end cmp ebx, 0x061000000 jz rbyte3 save: mov [edx], eax add edx, 4 jmp loop1 rbyte0: add eax, 0x00000002 jmp cbyte1 rbyte1: add eax, 0x00000200 jmp cbyte2 rbyte2: add eax, 0x00020000 jmp cbyte3 rbyte3: add eax, 0x02000000 jmp save end: mov [edx], eax } |
En nog iets: als ik mov edx, ebp gebruik ipv mov edx, [Str] (en Str locaal definieer) is ie ook heel wat sneller:
1
2
3
4
5
| Marcus_asm | Blablabla | 215.414808 ms OiSyN_asm1 | Blcblcblc | 407.912458 ms OiSyN_asm2 | Blablabla | 236.764728 ms Curry | Blcblcblc | 699.664902 ms Beelzebubu | Blcblcblc | 802.526019 ms |
Verwijderd
Hoe zou dat toch komenOp vrijdag 31 augustus 2001 12:29 schreef marcusk het volgende:
En nog iets: als ik mov edx, ebp gebruik ipv mov edx, [Str] (en Str locaal definieer) is ie ook heel wat sneller:
code:
1 2 Marcus_asm | Blablabla | 215.414808 ms ^^^^^^^^^^^

Dan doe ik het dus zo hé:Op vrijdag 31 augustus 2001 12:34 schreef beelzebubu het volgende:
Hoe zou dat toch komen
1
2
3
4
5
6
7
| void Marcus_asm() { char * Msg = TEST; _asm { mov edx, ebp ... |
Zzelfde manier als OiSyN_asm2. Dus hij doet het op zich wel, alleen zie je het resultaat niet, omdat ie werkt met een locale var.
Probeer:
1
2
3
4
5
| char* p = Msg; __asm { mov edx, p } |
Dat is nog minder snel dan mov edx, MsgOp vrijdag 31 augustus 2001 13:36 schreef OlafvdSpek het volgende:
Waarom toch al die truuks met ebp en esp?
Probeer:
code:
1 2 3 4 5 char* p = Msg; __asm { mov edx, p }
Verwijderd
Geen idee wat dat doetOp vrijdag 31 augustus 2001 13:19 schreef marcusk het volgende:
[..]
Dan doe ik het dus zo hé:
code:
1 2 3 4 5 6 7 void Marcus_asm() { char * Msg = TEST; _asm { mov edx, ebp ...
Zzelfde manier als OiSyN_asm2. Dus hij doet het op zich wel, alleen zie je het resultaat niet, omdat ie werkt met een locale var.
Mijn code om die Msg te printen was:
1
2
3
4
5
| #define Test(bla) \ [...] for (i=0;i<heleboel;i++) bla(i); [...] |
dus bla(i) in plaats van bla();
De functies zien er dan zo uit:
1
2
3
4
5
| void oisyn_asm(int i) { [...] if (!i) printf("%s - ", Msg); } |
en Test() print de rest erachteraan. Dus ook al is het lokale var, zou moeten werken. Of moet ik "lokaal" hier anders opvatten? Zoals ik al zei, ik snap werkelijk geen ene ..... van asm
[edit]
Daarbuiten, met optimalisatie 2 zag je *helemaal* geen resultaat bij oisyn/asm, hoe verklaren jullie dat dan?
die code klopt wel jaOp vrijdag 31 augustus 2001 14:11 schreef beelzebubu het volgende:
[..]
Geen idee wat dat doet![]()
Mijn code om die Msg te printen was:
code:
1 2 3 4 5 #define Test(bla) \ [...] for (i=0;i<heleboel;i++) bla(i); [...]
dus bla(i) in plaats van bla();
De functies zien er dan zo uit:
code:
1 2 3 4 5 void oisyn_asm(int i) { [...] if (!i) printf("%s - ", Msg); }
en Test() print de rest erachteraan. Dus ook al is het lokale var, zou moeten werken. Of moet ik "lokaal" hier anders opvatten? Zoals ik al zei, ik snap werkelijk geen ene ..... van asm
Ik heb geen idDaarbuiten, met optimalisatie 2 zag je *helemaal* geen resultaat bij oisyn/asm, hoe verklaren jullie dat dan?
Welke optimalizatie is dat?
Met de juiste optimalisatie van de compiler niet. Maar die instructie wilde VC niet compileren.Op vrijdag 31 augustus 2001 13:58 schreef marcusk het volgende:
[..]
Dat is nog minder snel dan mov edx, Msg
ja en dan geven jullie MIJ de schuld als ik er een foute "lea edx, [esp-0C]" van maak, dat heb IK niet gedaan!Op vrijdag 31 augustus 2001 14:53 schreef OlafvdSpek het volgende:
[..]
Met de juiste optimalisatie van de compiler niet. Maar die instructie wilde VC niet compileren.
werkt dit trouwens niet : "mov edx, offset Msg[0]" ?
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Verwijderd
Dat weet ik niet - moet je even de gcc-documentatie bekijkenOp vrijdag 31 augustus 2001 14:24 schreef marcusk het volgende:
Ik heb geen id
Welke optimalizatie is dat?
[edit] lees niet goed

Dat kan wel een access violation opleveren he?Op vrijdag 31 augustus 2001 12:29 schreef marcusk het volgende:
code:
1 2 3 4 mov edx, [Msg] loop1: mov eax, dword ptr [edx]
Je leest maximaal 3 bytes teveel in namelijk.
Daarom definieer ik Msg ook als char Msg[16];Op vrijdag 31 augustus 2001 16:58 schreef OlafvdSpek het volgende:
[..]
Dat kan wel een access violation opleveren he?
Je leest maximaal 3 bytes teveel in namelijk.

Mwah dat zit wel goed ... ff wat memrefs eruit halen:Op vrijdag 31 augustus 2001 00:50 schreef curry684 het volgende:
[..]
En da's lekker
Sowieso, ik vind dit gewoon teringgaaf. Ik word op m'n werk voor hacker uitgemaakt omdat C++ functies spontaan 3 keer sneller worden zodra je mij er een kwartier mee alleen laat (en niemand snapt er daarna nog een kont van maar het werkt wel, en snelllll), maar tegen dit totale asm-HACKHACKHACKwerk kan ik ook niet meer tegenop...
Overigens, het is een jaar of 6 geleden dat ik op de Amiga nog assembler programmeerde (laatste regel asm die ik ooit gedaan heb), maar ik wil nog wel een poginkje op MC680x0 assembler doen uit het blote hoofd:
code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Exchange: lea Message, a0 Loop1: cmp.b #'a', (a0) bne Loop2 move.b #'c', (a0)+ bra Loop1 Loop2: tst.b (a0)+ bne Loop1 rts Message: dc.b "Blablabla", 0
Kan
a) Iemand me vertellen hoeveel hout dit snijdt?
b) Iemand me vertellen waarom Intel in vergelijking met dit soort asm zo'n BAGGERINSTRUCTIESET heeft waardoor ik er nooit toe ben gekomen het te leren?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| exchange: lea.l message, a0 loop: move.b (a0)+,d0 beq.s done cmp.b #'a', d0 bne.s loop move.b #'c', (a0) bra.s loop done: rts message: dc.b "Blablabla", 0 |
Tis voor mij ook ff geleden ... dus check ut. Ik verbaas me ook nog steeds over wat voor baggerinstructieset de X88/X86 serie heeft. Ik vind de nieuwe MC860X0 syntax (pleur alles maar tussen ronde haken) echter ook niet zo mooi.
Hey ... maar dan heb je ook wat!
Hey ... maar dan heb je ook wat!
https://fgheysels.github.io/
Of zijn dat soort operaties daarmee niet mogelijk?
http://www.cpuid.com/Op zaterdag 01 september 2001 18:02 schreef OlafvdSpek het volgende:
Inderdaad. Heeft al iemand gedacht aan MMX/SSE?
Of zijn dat soort operaties daarmee niet mogelijk?
Daar staan de mmx en sse instructiesets. Ik geloof niet dat je daar iets aan hebt in dit geval
Ik zou het niet weten. Misschien is dat daar wel bruikbaar voor. Is er iemand met verstand van MMX?Op zaterdag 01 september 2001 21:11 schreef OlafvdSpek het volgende:
Jammer, iets als "Packed Bytes Compare for Equal" leek wel leuk. Kon je acht karakters tegelijk vergelijken.
dus je laadt zeg maar 8 bytes in in een mmx register, dan compare je dat met 'aaaaaaaa'. Alles bytes die gelijk zijn worden 0xff en alle bytes die ongelijk zijn worden 0x00. Deze uitkomst noemen we effe A.
Als je B = not A doet, dan heeft B precies het tegenovergestelde
het wordt dan
R = (MSG AND
als voorbeeld: MSG = "blablabl"
A = [0x00 0x00 0xff 0x00 0x00 0xff 0x00 0x00]
B = [0xff 0xff 0x00 0xff 0xff 0x00 0x00 0x00]
MSG AND B = 'bl_bl_bl' ('_' = 0x00)
'cccccccc' AND A = '__c__c__'
dus R = 'blcblcbl'
alleen dan moet je alleen nog testen waar de string eindigt, en de buffergrootte moet ook een veelvoud van 8 zijn
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
eerst verplaatsen naar een 32 bit register, en dan testen tegen 0.
mmxregister 32 bits shiften en verplaatsen naar 32 bits register en weer testen tegen 0
best wel omslachtig, maar een andere oplossing zou ik me niet voor kunnen stellen.
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
| void Marcus_mmx() { char * Msg = TEST; __asm { /* mov EDX, Msg // EDX: adres van Msg movq MM5, [g_AchtAs] // MM5: "aaaaaaaa" movq MM6, [g_Acht0s] // MM6: acht keer 0x00 movq MM7, [g_Acht2s] // MM7: acht keer 0x02 */ mov EDX, g_AchtAs movq MM5, [EDX] mov EDX, g_Acht0s movq MM6, [EDX] mov EDX, g_Acht2s movq MM7, [EDX] mov EDX, Msg mainloop: movq MM0, [EDX] // MM0: 8 bytes lezen movq MM1, MM0 // MM1: zelfde 8 bytes movq MM2, MM7 // MM2: acht keer 0x02 pcmpeqb MM0, MM6 // checken op \0 movd EAX, MM0 test EAX, EAX jnz klaar movq MM0, MM1 pcmpeqb MM0, MM5 // checken op a's pand MM2, MM0 paddb MM1, MM2 movq [EDX], MM1 // en weer terug schrijven add EDX, 8 // volgende 8 bytes checken jmp mainloop klaar: emms } } |
met:
1
2
3
4
5
6
| char * g_AchtAs = "\x61\x61\x61\x61\x61\x61\x61\x61"; // acht keer 'a' char * g_Acht0s = "\x00\x00\x00\x00\x00\x00\x00\x00"; // acht keer 0 char * g_Acht2s = "\x02\x02\x02\x02\x02\x02\x02\x02"; // acht keer 2 #define TEST "blablablablablablablablablablablablablablabla blablablablablablaa\0\0\0\0\0\0\0\0" |
goh, dat heeft zin gehad:
1
2
3
4
5
| Marcus_asm | 1389.306183 ms Marcus_mmx | 1184.645814 ms OiSyN_asm | 1762.608935 ms Curry | 1865.880440 ms Beelzebubu | 2307.248268 ms |
Nouja... mijn eerste MMX-proggel
1
2
3
| movq MM5, [g_AchtAs] // MM5: "aaaaaaaa" movq MM6, [g_Acht0s] // MM6: acht keer 0x00 movq MM7, [g_Acht2s] // MM7: acht keer 0x02 |
waarom werkt dit eigenlijk niet?
het compiled wel enzo, maar hij zet de geheugenadressen van de vars in de mmx-registers i.p.v. de data
dus je moet doen:
1
2
| char achtA[8] = "aaaaaaaa"; ... |
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
ach natuurlijk. stom van me.Op zondag 02 september 2001 15:39 schreef OiSyN het volgende:
logisch, op het adres van die variabelen staat het adres naar de buffer waar die chars in staan (zie ook het begin van dit topic: het verschil tussen char * en char [])
dus je moet doen:
code:
1 2 char achtA[8] = "aaaaaaaa"; ...
het gaat trouwens niet echt sneller op deze manier.
Ik was na 2 reply's al tevreden, maar ja. Wel leuk om te zien dat er om een simpel vraagje 8 pagina's vol gelult wordt. Het lijkt wel een chat-box.
Veel plezier met het verbeteren van jullie bikkel-code... Ik blijf bij m'n oude...
we zullen je nog eens helpen!
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
We hebben nu allemaal een supersnelle char replace functie ;->
das waar.... ik zal m gelijk in mijn 3d engine stoppenOp dinsdag 04 september 2001 14:58 schreef OlafvdSpek het volgende:
Het was toch niet voor niks?
We hebben nu allemaal een supersnelle char replace functie ;->
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.