Gjest Slettet+9871234 Skrevet 8. september 2012 Del Skrevet 8. september 2012 (endret) Dette burde være av interesse for dere som jobber med Assembly generelt og i C++ spesielt. Det er enkelt å integrere inline assembly instruksjoner i C++Builder. RAD Studio XE3 World Tour i Oslo Oslo 13 september 2012 Håndverkeren Kurs- og Konferansesenter, Rosenkrantzgate 7 0159 Oslo Embarcaderos hjemmeside: http://www.embarcadero.com/ Jeg har fulgt C++ fra den var eid av Borland. Nå eies som kjent RAD Studio XE3 som inneholder C++Builder samt Delhi (Skype ble utviklet i Delphi) av Embarcadero. Endret 8. september 2012 av Slettet+9871234 Lenke til kommentar
LonelyMan Skrevet 8. september 2012 Del Skrevet 8. september 2012 (endret) Min rot13 funksjon roterer strenger med en hastighet på 2,2 bytes per nano sekund (2,23 GB per sekund). Jeg har ikke forsøkt å optimalisere den videre ennå. Men se om du kan slå den først. Jeg har ikke anelse hvor dette ligger hen i forhold til et liknende c++ program, så jeg må bare se meg frem her. Rot13Buf4 DB 0,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 DB 27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50 DB 51,52,53,54,55,56,57,58,59,60,61,62,63,64 DB "NOPQRSTUVWXYZABCDEFGHIJKLM" DB 91,92,93,94,95,96 DB "nopqrstuvwxyzabcdefghijklm" DB 123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142 DB 143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162 DB 163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182 DB 183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202 DB 203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222 DB 223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242 DB 243,244,245,246,247,248,249,250,251,252,253,254,255 .CODE OPTION PROLOGUE:NONE OPTION EPILOGUE:NONE ALIGN 16 Rot13L8 PROC push ebx push edi xor ecx, ecx xor edx, edx mov edi, OFFSET Rot13Buf4 ALIGN 16 @@: mov eax, [esi] mov ebx, [esi+4] mov cl, al mov dl, ah mov cl, [edi+ecx] mov dl, [edi+edx] shr eax, 16 mov [esi], cl mov [esi+1], dl mov cl, al mov dl, ah mov [esi+2], cl mov [esi+3], dl mov cl, bl mov dl, bh mov cl, [edi+ecx] mov eax, esi mov dl, [edi+edx] shr ebx, 16 add esi, 8 sub ebp, 1 mov [eax+4], cl mov [eax+5], dl mov cl, bl mov dl, bh mov [eax+6], cl mov [eax+7], dl jnz @B pop edi pop ebx ret Rot13L8 ENDP Endret 8. september 2012 av LonelyMan Lenke til kommentar
Gjest Slettet+9871234 Skrevet 8. september 2012 Del Skrevet 8. september 2012 Glimrende, selv om jeg er langt borte fra C++ og Assembly nå. Trist at ikke flere deltar her. Fikk dere med dere disse http://www.kjellbleivik.com/Books/#assembly ressursene? Lenke til kommentar
GeirGrusom Skrevet 8. september 2012 Del Skrevet 8. september 2012 Hvorfor bruker du 32-bit assembly her? Lenke til kommentar
Gjest Slettet+9871234 Skrevet 8. september 2012 Del Skrevet 8. september 2012 (endret) Ja jeg så at han blandet det. Bastarder skal jo være de sterkeste hundene. Endret 8. september 2012 av Slettet+9871234 Lenke til kommentar
Drogin Skrevet 8. september 2012 Del Skrevet 8. september 2012 (endret) Hva legger du i string rotation? Å flytte alle bokstaver i strengen "ett hakk frem", og la første bokstav ende på siste bokstav? Edit: Nvm, du tenker på cipheret ja,ok Endret 8. september 2012 av Drogin Lenke til kommentar
GeirGrusom Skrevet 8. september 2012 Del Skrevet 8. september 2012 All respekt til deg, LonelyMan, som bruker Assembly på denne måten, men jeg kan ikke riste av meg følelsen at det er ganske bortkastet tid. Her er Visual C++ sin output fra følgende kode. Mulig jeg har missforstått ROT-13, si ifra isåfall: extern "C" { void Rot13_C(const char* input, const size_t size, char* output) { for(auto i = 0; i < size; i++) { if((input[i] >= 'a' && input[i] <= 'z') || (input[i] >= 'A' && input[i] <= 'Z')) { auto offset = input[i] >= 'a' && input[i] <= 'z' ? 'a' : 'A'; output[i] = (char)((input[i] + 13) - offset) % ('z' - 'a') + offset; } else output[i] = input[i]; } output[size] = 0; } } Assembly output fra compileren: Rot13_C PROC ; COMDAT ; 22 : { $LN19: push rdi ; 23 : for(auto i = 0; i < size; i++) xor r10d, r10d mov rdi, r8 mov r11, rdx test rdx, rdx je $LN17@Rot13_C mov QWORD PTR [rsp+16], rbx lea r9, OFFSET FLAT:??_C@_0EG@CHCBLGHC@A?5rotate?5buffer?5must?5be?5rotated?5@ mov rbx, r8 mov QWORD PTR [rsp+24], rsi lea esi, QWORD PTR [r10+97] sub rbx, r9 npad 1 $LL7@Rot13_C: ; 24 : { ; 25 : if((input[i] >= 'a' && input[i] <= 'z') || (input[i] >= 'A' && input[i] <= 'Z')) movzx eax, BYTE PTR [r9] lea ecx, DWORD PTR [rax-97] cmp cl, 25 jbe SHORT $LN3@Rot13_C lea ecx, DWORD PTR [rax-65] cmp cl, 25 jbe SHORT $LN3@Rot13_C ; 29 : } ; 30 : else ; 31 : output[i] = input[i]; mov BYTE PTR [rbx+r9], al jmp SHORT $LN6@Rot13_C $LN3@Rot13_C: lea ecx, DWORD PTR [rax-97] mov r8d, 65 ; 00000041H cmp cl, 25 cmovbe r8d, esi ; 26 : { ; 27 : auto offset = input[i] >= 'a' && input[i] <= 'z' ? 'a' : 'A'; ; 28 : output[i] = (char)((input[i] + 13) - offset) % ('z' - 'a') + offset; sub al, r8b add al, 13 movsx ecx, al mov eax, 1374389535 ; 51eb851fH imul ecx sar edx, 3 mov eax, edx shr eax, 31 add edx, eax imul edx, 25 sub ecx, edx add cl, r8b mov BYTE PTR [rbx+r9], cl $LN6@Rot13_C: ; 23 : for(auto i = 0; i < size; i++) inc r10d inc r9 movsxd rax, r10d cmp rax, r11 jb SHORT $LL7@Rot13_C ; 32 : } ; 33 : output[size] = 0; mov rsi, QWORD PTR [rsp+24] mov rbx, QWORD PTR [rsp+16] mov BYTE PTR [r11+rdi], 0 På denne maskinen resulterte det i 14.7 bytes per nanosekund. Lenke til kommentar
LonelyMan Skrevet 8. september 2012 Del Skrevet 8. september 2012 (endret) Punkt 1: Du kjører 64 bits kode. Punkt 2: 14,7 bytes per nanosekund er umulig for dagens datamaskiner. he-he Det er en alvorlig feil en plass her ja. Det er garantert. Endret 8. september 2012 av LonelyMan Lenke til kommentar
Gjest Slettet+9871234 Skrevet 8. september 2012 Del Skrevet 8. september 2012 Skulle gjerne sett ASM output fra siste versjon av RAD studio XE III C++ Builder. P.S. <off topic> Dette Embarcadero HTML5 Builder Revolutionizes Mobile and Web App Development Here comes the iPhone 5 burde interessere noen av dere frontrunnere. Hva med assembly på iPhone5 og andre mobiltelefoner som jo ikke er noe annet enn en datamaskin, dog med svak sikkerhet. </off topic> Lenke til kommentar
GeirGrusom Skrevet 8. september 2012 Del Skrevet 8. september 2012 (endret) Punkt 1: Du kjører 64 bits kode. Punkt 2: 14,7 bytes per nanosekund er umulig for dagens datamaskiner. he-he Det er en alvorlig feil en plass her ja. Det er garantert. Ah jeg som hadde gjort feil men beregningen. Det var ikke i nærheten engang, 0.06 bytes per nanosekund :/ Men jeg kan vel med fordel bruke en lookup tabell slik som du gjør også. Endret 8. september 2012 av GeirGrusom Lenke til kommentar
GeirGrusom Skrevet 8. september 2012 Del Skrevet 8. september 2012 Skulle gjerne sett ASM output fra siste versjon av RAD studio XE III C++ Builder. Visual C++ og GCC har ihvertfall flagg for å gi ifra seg assembly-kode til output, så går utifra at C++Builder har det samme. Lenke til kommentar
LonelyMan Skrevet 8. september 2012 Del Skrevet 8. september 2012 (endret) Det er utrolig hvor mye data man kan behandle samtidig med 64 bit registre. Jeg skal snart hoppe fra 32 bit for godt og begynne på 64 bit. Men da skal jeg begynne med JWasm istedet for Masm. Eventuelt Fasm. Endret 8. september 2012 av LonelyMan Lenke til kommentar
Gjest Slettet+9871234 Skrevet 8. september 2012 Del Skrevet 8. september 2012 Skulle gjerne sett ASM output fra siste versjon av RAD studio XE III C++ Builder. Visual C++ og GCC har ihvertfall flagg for å gi ifra seg assembly-kode til output, så går utifra at C++Builder har det samme. Ja det er svært enkelt, men jeg har ikke siste versjon eller tid til å teste det på eldre versjoner. Lenke til kommentar
Gjest Slettet+9871234 Skrevet 8. september 2012 Del Skrevet 8. september 2012 Det er utrolig hvor mye data man kan behandle samtidig med 64 bit registre. Jeg skal snart hoppe fra 32 bit for godt og begynne på 64 bit. Men da skal jeg begynne med JWasm istedet for Masm. Eventuelt Fasm. Vil det si at segmenter fra 16 bits teknologi ikke lenger er aktuelt? Med andre ord, kan man spare tid på å blande 16, 32 og 64 bits teknologier som jeg var inne på tidligere eller er det uaktuelt med 64 bits teknologier. Kanskje et dumt spørsmål, er der i analogi med mengdelære et indre snitt av instruksjoner som deler av et program kan kjøre på for å øke hastigjheten. Nesten som i Drupal kjernen ... Lenke til kommentar
Drogin Skrevet 8. september 2012 Del Skrevet 8. september 2012 (endret) Jeg får ut 2,72GB pr sekund...mer enn hva programmet skrevet i assembler fikk ut. Men det kan jo være forskjell på prosessorene våre. 100MB går på 43 - 44ms. Input er 100MB med random generert strings med både store og små bokstaver. Prøv å kjør den hos deg. (NB, jeg var lat når jeg laget koden for å time funksjonen min, så bruker den mer enn 1000ms skriver den ut rare verdier). Assemlby output: ; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01 include listing.inc INCLUDELIB OLDNAMES PUBLIC ?lookup@@3PADA ; lookup EXTRN __imp__time64:PROC EXTRN __imp_rand:PROC EXTRN __imp_srand:PROC EXTRN __imp_getchar:PROC EXTRN __imp_printf:PROC EXTRN __imp_free:PROC EXTRN __imp_malloc:PROC EXTRN __imp_GetLocalTime:PROC ?lookup@@3PADA DB 0100H DUP (?) ; lookup $SG-7 DB 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 00H ORG $+3 $SG-8 DB '100 Megabytes took %d milliseconds.', 0aH, 00H PUBLIC ?createLookup@@YAXXZ ; createLookup ; Function compile flags: /Ogtpy _TEXT SEGMENT ?createLookup@@YAXXZ PROC ; createLookup ; File d:\projects\arraytester\arraytester\arraytester.cpp ; Line 27 xor eax, eax lea rcx, OFFSET FLAT:?lookup@@3PADA ; lookup npad 7 $LL13@createLook: ; Line 28 mov BYTE PTR [rcx], al inc eax inc rcx cmp eax, 256 ; 00000100H jl SHORT $LL13@createLook ; Line 31 mov ecx, 65 ; 00000041H lea rdx, OFFSET FLAT:?lookup@@3PADA+65 npad 6 $LL10@createLook: ; Line 33 lea eax, DWORD PTR [rcx+13] cmp ecx, 77 ; 0000004dH jle SHORT $LN22@createLook ; Line 35 lea eax, DWORD PTR [rcx-13] $LN22@createLook: ; Line 31 inc ecx ; Line 35 mov BYTE PTR [rdx], al inc rdx cmp ecx, 90 ; 0000005aH jle SHORT $LL10@createLook ; Line 39 mov ecx, 97 ; 00000061H lea rdx, OFFSET FLAT:?lookup@@3PADA+97 $LL5@createLook: ; Line 41 lea eax, DWORD PTR [rcx+13] cmp ecx, 109 ; 0000006dH jle SHORT $LN23@createLook ; Line 43 lea eax, DWORD PTR [rcx-13] $LN23@createLook: ; Line 39 inc ecx ; Line 43 mov BYTE PTR [rdx], al inc rdx cmp ecx, 122 ; 0000007aH jle SHORT $LL5@createLook ; Line 46 fatret 0 ?createLookup@@YAXXZ ENDP ; createLookup _TEXT ENDS PUBLIC ?stringRotation@@YAXPEADH@Z ; stringRotation ; Function compile flags: /Ogtpy _TEXT SEGMENT text$ = 8 ?stringRotation@@YAXPEADH@Z PROC ; stringRotation ; Line 22 inc rcx mov edx, 20000000 ; 01312d00H lea r8, OFFSET FLAT:?lookup@@3PADA ; lookup npad 1 $LL3@stringRota: movsx rax, BYTE PTR [rcx-1] add rcx, 5 dec rdx movzx eax, BYTE PTR [rax+r8] mov BYTE PTR [rcx-6], al movsx rax, BYTE PTR [rcx-5] movzx eax, BYTE PTR [rax+r8] mov BYTE PTR [rcx-5], al movsx rax, BYTE PTR [rcx-4] movzx eax, BYTE PTR [rax+r8] mov BYTE PTR [rcx-4], al movsx rax, BYTE PTR [rcx-3] movzx eax, BYTE PTR [rax+r8] mov BYTE PTR [rcx-3], al movsx rax, BYTE PTR [rcx-2] movzx eax, BYTE PTR [rax+r8] mov BYTE PTR [rcx-2], al jne SHORT $LL3@stringRota ; Line 24 fatret 0 ?stringRotation@@YAXPEADH@Z ENDP ; stringRotation ; Function compile flags: /Ogtpy time PROC ; File d:\program files (x86)\microsoft visual studio 10.0\vc\include\time.inl ; Line 133 xor ecx, ecx ; Line 134 rex_jmp QWORD PTR __imp__time64 time ENDP _TEXT ENDS PUBLIC ?randomStrGen@@YAXPEADH@Z ; randomStrGen pdata SEGMENT $pdata$?randomStrGen@@YAXPEADH@Z DD imagerel $LN10 DD imagerel $LN10+131 DD imagerel $unwind$?randomStrGen@@YAXPEADH@Z pdata ENDS xdata SEGMENT $unwind$?randomStrGen@@YAXPEADH@Z DD 081401H DD 086414H DD 075414H DD 063414H DD 070103214H ; Function compile flags: /Ogtpy xdata ENDS _TEXT SEGMENT str$ = 48 ?randomStrGen@@YAXPEADH@Z PROC ; randomStrGen ; File d:\projects\arraytester\arraytester\arraytester.cpp ; Line 12 $LN10: mov QWORD PTR [rsp+8], rbx mov QWORD PTR [rsp+16], rbp mov QWORD PTR [rsp+24], rsi push rdi sub rsp, 32 ; 00000020H mov rdi, rcx ; Line 14 xor ecx, ecx call QWORD PTR __imp__time64 mov rcx, rax call QWORD PTR __imp_srand ; Line 15 xor ebx, ebx mov rsi, 5675921253449092805 ; 4ec4ec4ec4ec4ec5H lea rbp, OFFSET FLAT:$SG-7 npad 5 $LL3@randomStrG: ; Line 16 call QWORD PTR __imp_rand inc rbx movsxd rcx, eax mov rax, rsi mul rcx shr rdx, 4 imul rdx, 52 ; 00000034H sub rcx, rdx movzx eax, BYTE PTR [rcx+rbp] mov BYTE PTR [rbx+rdi-1], al cmp rbx, 99999999 ; 05f5e0ffH jl SHORT $LL3@randomStrG ; Line 17 mov rbx, QWORD PTR [rsp+48] mov rbp, QWORD PTR [rsp+56] mov rsi, QWORD PTR [rsp+64] add rsp, 32 ; 00000020H pop rdi ret 0 ?randomStrGen@@YAXPEADH@Z ENDP ; randomStrGen _TEXT ENDS PUBLIC main EXTRN memset:PROC pdata SEGMENT $pdata$main DD imagerel $LN34 DD imagerel $LN34+316 DD imagerel $unwind$main pdata ENDS xdata SEGMENT $unwind$main DD 040a01H DD 0a340aH DD 07006720aH ; Function compile flags: /Ogtpy xdata ENDS _TEXT SEGMENT before$ = 32 after$ = 48 argc$ = 80 argv$ = 88 main PROC ; Line 49 $LN34: mov QWORD PTR [rsp+8], rbx push rdi sub rsp, 64 ; 00000040H ; Line 53 mov ecx, 100000000 ; 05f5e100H call QWORD PTR __imp_malloc ; Line 54 xor edx, edx mov r8d, 100000000 ; 05f5e100H mov rcx, rax mov rbx, rax call memset ; Line 55 mov rcx, rbx call ?randomStrGen@@YAXPEADH@Z ; randomStrGen lea rdi, OFFSET FLAT:?lookup@@3PADA ; lookup ; Line 59 xor r11d, r11d mov rcx, rdi npad 3 $LL15@main: mov BYTE PTR [rcx], r11b inc r11d inc rcx cmp r11d, 256 ; 00000100H jl SHORT $LL15@main mov ecx, 65 ; 00000041H lea rdx, OFFSET FLAT:?lookup@@3PADA+65 npad 2 $LL12@main: lea eax, DWORD PTR [rcx+13] cmp ecx, 77 ; 0000004dH jle SHORT $LN32@main lea eax, DWORD PTR [rcx-13] $LN32@main: inc ecx mov BYTE PTR [rdx], al inc rdx cmp ecx, 90 ; 0000005aH jle SHORT $LL12@main mov ecx, 97 ; 00000061H lea rdx, OFFSET FLAT:?lookup@@3PADA+97 $LL7@main: lea eax, DWORD PTR [rcx+13] cmp ecx, 109 ; 0000006dH jle SHORT $LN33@main lea eax, DWORD PTR [rcx-13] $LN33@main: inc ecx mov BYTE PTR [rdx], al inc rdx cmp ecx, 122 ; 0000007aH jle SHORT $LL7@main ; Line 63 lea rcx, QWORD PTR before$[rsp] call QWORD PTR __imp_GetLocalTime lea r11, QWORD PTR [rbx+1] mov ecx, 20000000 ; 01312d00H npad 2 ; Line 65 $LL20@main: movsx rax, BYTE PTR [r11-1] add r11, 5 dec rcx movzx eax, BYTE PTR [rax+rdi] mov BYTE PTR [r11-6], al movsx rax, BYTE PTR [r11-5] movzx eax, BYTE PTR [rax+rdi] mov BYTE PTR [r11-5], al movsx rax, BYTE PTR [r11-4] movzx eax, BYTE PTR [rax+rdi] mov BYTE PTR [r11-4], al movsx rax, BYTE PTR [r11-3] movzx eax, BYTE PTR [rax+rdi] mov BYTE PTR [r11-3], al movsx rax, BYTE PTR [r11-2] movzx eax, BYTE PTR [rax+rdi] mov BYTE PTR [r11-2], al jne SHORT $LL20@main ; Line 68 lea rcx, QWORD PTR after$[rsp] call QWORD PTR __imp_GetLocalTime ; Line 71 movzx r11d, WORD PTR before$[rsp+14] movzx edx, WORD PTR after$[rsp+14] lea rcx, OFFSET FLAT:$SG-8 sub edx, r11d call QWORD PTR __imp_printf ; Line 74 call QWORD PTR __imp_getchar ; Line 75 mov rcx, rbx call QWORD PTR __imp_free ; Line 77 mov rbx, QWORD PTR [rsp+80] xor eax, eax add rsp, 64 ; 00000040H pop rdi ret 0 main ENDP _TEXT ENDS END ArrayTester.zip Endret 8. september 2012 av Drogin Lenke til kommentar
Gjest Slettet+9871234 Skrevet 8. september 2012 Del Skrevet 8. september 2012 (endret) Hva er det man egentlig tester her? Gjentatte identiske operasjoner med ulik input? Hvor godt er det i så fall egnet til å teste det man egentlig skal teste slik jeg har forstått problemstillingen? Er der mønstre i din kode, burde LonelyMan kunne benytte det til å lage en mer effektiv kode. Hvis man tester gjentatte identiske operasjoner, hvor godt egnet er det til å teste om en assembly programmere er bedre enn en optimaliserende moderne kompilator? En presisering av oppgaven hadde gjerne vært på sin plass. Det er selvsagt helt fundamentalt at kodene testes på samme datamaskin. Der er forskjell på en isomorfi og en polymorfi. Endret 8. september 2012 av Slettet+9871234 Lenke til kommentar
LonelyMan Skrevet 8. september 2012 Del Skrevet 8. september 2012 Det ser riktig ut Drogin, men dog 64 bit (jeg bruker 32 bit) Lenke til kommentar
LonelyMan Skrevet 8. september 2012 Del Skrevet 8. september 2012 (endret) I tillegg er det 8 nye registre tilgjengelig, så mange nye registre er devastating for ytelse. Jeg vet ikke om du får kompilert samme eksemplet for win32, du kan prøve. La meg få vite resultatet da. Men uansett, god ytelse. Endret 8. september 2012 av LonelyMan Lenke til kommentar
Gjest Slettet+9871234 Skrevet 8. september 2012 Del Skrevet 8. september 2012 (endret) Det ser riktig ut Drogin, men dog 64 bit (jeg bruker 32 bit) Da bruker man vel strengt tatt ulik underliggende platform. Blir spennende å se din eventuelle 64 bits løsning. Det forundrer vel heller ingen at en kompilator kan slå en ASM programmerer på deler av en kode. Da er spørsmålene Hvor komplesk er koden i betydningen ikke repeterende instruksjoner (som vel kan puttes i en sub rutine)? Kan programmereren studere ASM output fra kompilatoren og forbedre sin kode der den er mindre effektiv? Kan kompilatoren gjøre det samme? Er der noe for en programmerer å vinne på reverse engineering (disassemblering) av C / C++ exe koden med flere pass gjennom koden? Endret 8. september 2012 av Slettet+9871234 Lenke til kommentar
LonelyMan Skrevet 8. september 2012 Del Skrevet 8. september 2012 kgun, det er ikke uvanlig for en assembler programmerer å først kjøre en pseudo kode gjennom en kompilator med full optimalisering, deretter å plukke ut assembler koden og så optimalisere den for hånd. Det er faktisk veldig vanlig. Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå