jonny Skrevet 30. september 2012 Del Skrevet 30. september 2012 Bruker ikke widechars, jeg, kan du peke på hva i koden som sier at jeg gjør det? Koden er ANSI C (ikke C++-kode). Kan godt legge ut assembler-koden som blir generert, men det er relativt mange kodelinjer... Lenke til kommentar
LonelyMan Skrevet 30. september 2012 Del Skrevet 30. september 2012 Bare glem det, det var han andre som brukte widechar, ikke du. Lenke til kommentar
Paull Skrevet 30. september 2012 Del Skrevet 30. september 2012 (endret) LonelyMan, du har rett, jeg hadde et par bugs i koden. Har nå tatt i bruk den nye implementasjonen av randomStrGen fra jonny, i tillegg til å faktisk kalle funksjonen som genererer den nye tabellen. Throughput er omtrent den samme dog; 100 Megabytes took 14.896170 milliseconds.MB/s = 6713.135208 Assembly: ; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.40219.01 TITLE C:\Users\xxx\documents\visual studio 2010\Projects\Rot13Test\Rot13Test\rot13.cpp .686P .XMM include listing.inc .model flat INCLUDELIB OLDNAMES PUBLIC ?PCFreq@@3NA ; PCFreq PUBLIC ?CounterStart@@3_JA ; CounterStart PUBLIC ??_C@_0DF@MEPDHLIP@abcdefghijklmnopqrstuvwxyzABCDEF@ ; `string' PUBLIC ??_C@_0BD@ONNLNDEL@QPC?5did?5not?5work?4?4?$AA@ ; `string' PUBLIC ??_C@_0CF@MOIGNLJO@100?5Megabytes?5took?5?$CFf?5millisecon@ ; `string' PUBLIC ??_C@_09IJINBEEB@MB?1s?5?$DN?5?$CFf?$AA@ ; `string' EXTRN __imp__QueryPerformanceFrequency@4:PROC EXTRN __imp__QueryPerformanceCounter@4:PROC EXTRN __imp__free:PROC EXTRN __imp__malloc:PROC EXTRN __imp__printf:PROC EXTRN __imp__rand:PROC EXTRN __imp__srand:PROC EXTRN __imp___time64:PROC ?PCFreq@@3NA DQ 01H DUP (?) ; PCFreq ?CounterStart@@3_JA DQ 01H DUP (?) ; CounterStart ; COMDAT ??_C@_09IJINBEEB@MB?1s?5?$DN?5?$CFf?$AA@ CONST SEGMENT ??_C@_09IJINBEEB@MB?1s?5?$DN?5?$CFf?$AA@ DB 'MB/s = %f', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0CF@MOIGNLJO@100?5Megabytes?5took?5?$CFf?5millisecon@ CONST SEGMENT ??_C@_0CF@MOIGNLJO@100?5Megabytes?5took?5?$CFf?5millisecon@ DB '100 Megab' DB 'ytes took %f milliseconds.', 0aH, 00H ; `string' CONST ENDS ; COMDAT ??_C@_0BD@ONNLNDEL@QPC?5did?5not?5work?4?4?$AA@ CONST SEGMENT ??_C@_0BD@ONNLNDEL@QPC?5did?5not?5work?4?4?$AA@ DB 'QPC did not work..', 00H ; `string' CONST ENDS ; COMDAT ??_C@_0DF@MEPDHLIP@abcdefghijklmnopqrstuvwxyzABCDEF@ CONST SEGMENT ??_C@_0DF@MEPDHLIP@abcdefghijklmnopqrstuvwxyzABCDEF@ DB 'abcdefghijklmnop' DB 'qrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 00H ; `string' CONST ENDS PUBLIC ?createLookupWide@@YAXXZ ; createLookupWide _lookupWide DW 010000H DUP (?) _lookup DB 0100H DUP (?) ; Function compile flags: /Ogtp ; COMDAT ?createLookupWide@@YAXXZ _TEXT SEGMENT ?createLookupWide@@YAXXZ PROC ; createLookupWide, COMDAT ; File c:\users\xxx\documents\visual studio 2010\projects\rot13test\rot13test\rot13.cpp ; Line 91 xor eax, eax $LL3@createLook: ; Line 93 mov ecx, eax sar ecx, 8 ; Line 95 movsx edx, cl movsx cx, BYTE PTR _lookup[edx] movsx edx, al movzx edx, BYTE PTR _lookup[edx] shl cx, 8 or cx, dx mov WORD PTR _lookupWide[eax*2], cx inc eax cmp eax, 65536 ; 00010000H jl SHORT $LL3@createLook ; Line 132 ret 0 ?createLookupWide@@YAXXZ ENDP ; createLookupWide _TEXT ENDS PUBLIC ?createLookup@@YAXXZ ; createLookup ; Function compile flags: /Ogtp ; COMDAT ?createLookup@@YAXXZ _TEXT SEGMENT ?createLookup@@YAXXZ PROC ; createLookup, COMDAT ; Line 63 xor eax, eax $LL13@createLook@2: ; Line 64 mov BYTE PTR _lookup[eax], al inc eax cmp eax, 256 ; 00000100H jl SHORT $LL13@createLook@2 ; Line 67 mov eax, 65 ; 00000041H $LL10@createLook@2: ; Line 68 cmp eax, 77 ; 0000004dH jg SHORT $LN7@createLook@2 ; Line 69 lea ecx, DWORD PTR [eax+13] mov BYTE PTR _lookup[eax], cl ; Line 70 jmp SHORT $LN9@createLook@2 $LN7@createLook@2: ; Line 71 lea edx, DWORD PTR [eax-13] mov BYTE PTR _lookup[eax], dl $LN9@createLook@2: ; Line 67 inc eax cmp eax, 90 ; 0000005aH jle SHORT $LL10@createLook@2 ; Line 75 mov eax, 97 ; 00000061H npad 7 $LL5@createLook@2: ; Line 76 cmp eax, 109 ; 0000006dH jg SHORT $LN2@createLook@2 ; Line 77 lea ecx, DWORD PTR [eax+13] mov BYTE PTR _lookup[eax], cl ; Line 78 jmp SHORT $LN4@createLook@2 $LN2@createLook@2: ; Line 79 lea edx, DWORD PTR [eax-13] mov BYTE PTR _lookup[eax], dl $LN4@createLook@2: ; Line 75 inc eax cmp eax, 122 ; 0000007aH jle SHORT $LL5@createLook@2 ; Line 82 ret 0 ?createLookup@@YAXXZ ENDP ; createLookup _TEXT ENDS PUBLIC ?stringRotation@@YAXPAEH@Z ; stringRotation ; Function compile flags: /Ogtp ; COMDAT ?stringRotation@@YAXPAEH@Z _TEXT SEGMENT ?stringRotation@@YAXPAEH@Z PROC ; stringRotation, COMDAT ; _text$ = eax ; Line 52 inc eax mov ecx, 5000000 ; 004c4b40H npad 10 $LL3@stringRota: ; Line 57 movzx edx, BYTE PTR [eax-1] movzx edx, BYTE PTR _lookupWide[edx*2] mov BYTE PTR [eax-1], dl movzx edx, BYTE PTR [eax] movzx edx, BYTE PTR _lookupWide[edx*2] mov BYTE PTR [eax], dl movzx edx, BYTE PTR [eax+1] movzx edx, BYTE PTR _lookupWide[edx*2] mov BYTE PTR [eax+1], dl movzx edx, BYTE PTR [eax+2] movzx edx, BYTE PTR _lookupWide[edx*2] mov BYTE PTR [eax+2], dl movzx edx, BYTE PTR [eax+3] movzx edx, BYTE PTR _lookupWide[edx*2] mov BYTE PTR [eax+3], dl add eax, 5 dec ecx jne SHORT $LL3@stringRota ; Line 59 ret 0 ?stringRotation@@YAXPAEH@Z ENDP ; stringRotation _TEXT ENDS PUBLIC ?GetCounter@@YANXZ ; GetCounter EXTRN __fltused:DWORD ; Function compile flags: /Ogtp ; COMDAT ?GetCounter@@YANXZ _TEXT SEGMENT tv73 = -8 ; size = 8 _li$ = -8 ; size = 8 ?GetCounter@@YANXZ PROC ; GetCounter, COMDAT ; Line 22 push ebp mov ebp, esp sub esp, 8 ; Line 24 lea eax, DWORD PTR _li$[ebp] push eax call DWORD PTR __imp__QueryPerformanceCounter@4 ; Line 25 mov ecx, DWORD PTR _li$[ebp] sub ecx, DWORD PTR ?CounterStart@@3_JA mov edx, DWORD PTR _li$[ebp+4] sbb edx, DWORD PTR ?CounterStart@@3_JA+4 mov DWORD PTR tv73[ebp], ecx mov DWORD PTR tv73[ebp+4], edx fild QWORD PTR tv73[ebp] fdiv QWORD PTR ?PCFreq@@3NA ; PCFreq ; Line 26 mov esp, ebp pop ebp ret 0 ?GetCounter@@YANXZ ENDP ; GetCounter _TEXT ENDS PUBLIC __real@408f400000000000 PUBLIC ?StartCounter@@YAXXZ ; StartCounter ; COMDAT __real@408f400000000000 CONST SEGMENT __real@408f400000000000 DQ 0408f400000000000r ; 1000 ; Function compile flags: /Ogtp CONST ENDS ; COMDAT ?StartCounter@@YAXXZ _TEXT SEGMENT _li$ = -8 ; size = 8 ?StartCounter@@YAXXZ PROC ; StartCounter, COMDAT ; Line 11 push ebp mov ebp, esp sub esp, 8 ; Line 13 lea eax, DWORD PTR _li$[ebp] push eax call DWORD PTR __imp__QueryPerformanceFrequency@4 test eax, eax je SHORT $LN2@StartCount ; Line 16 fild QWORD PTR _li$[ebp] ; Line 18 lea ecx, DWORD PTR _li$[ebp] push ecx fdiv QWORD PTR __real@408f400000000000 fstp QWORD PTR ?PCFreq@@3NA ; PCFreq call DWORD PTR __imp__QueryPerformanceCounter@4 ; Line 19 mov edx, DWORD PTR _li$[ebp] mov eax, DWORD PTR _li$[ebp+4] mov DWORD PTR ?CounterStart@@3_JA, edx mov DWORD PTR ?CounterStart@@3_JA+4, eax $LN2@StartCount: ; Line 20 mov esp, ebp pop ebp ret 0 ?StartCounter@@YAXXZ ENDP ; StartCounter ; Function compile flags: /Ogtp _TEXT ENDS ; COMDAT _time _TEXT SEGMENT _time PROC ; COMDAT ; File c:\program files (x86)\microsoft visual studio 10.0\vc\include\time.inl ; Line 133 push 0 call DWORD PTR __imp___time64 add esp, 4 ; Line 134 ret 0 _time ENDP ; Function compile flags: /Ogtp _TEXT ENDS ; COMDAT ?randomStrGen@@YAXPAEH@Z _TEXT SEGMENT ?randomStrGen@@YAXPAEH@Z PROC ; randomStrGen, COMDAT ; _str$ = ebx ; File c:\users\xxx\documents\visual studio 2010\projects\rot13test\rot13test\rot13.cpp ; Line 40 push esi push edi ; Line 41 push 0 call DWORD PTR __imp___time64 push eax call DWORD PTR __imp__srand ; Line 43 mov edi, DWORD PTR __imp__rand add esp, 8 xor esi, esi npad 4 $LL3@randomStrG: ; Line 44 call edi and eax, -2147483393 ; 800000ffH jns SHORT $LN10@randomStrG dec eax or eax, -256 ; ffffff00H inc eax $LN10@randomStrG: mov BYTE PTR [esi+ebx], al inc esi cmp esi, 99999999 ; 05f5e0ffH jl SHORT $LL3@randomStrG ; Line 45 pop edi pop esi ret 0 ?randomStrGen@@YAXPAEH@Z ENDP ; randomStrGen _TEXT ENDS PUBLIC __real@4059000000000000 PUBLIC __real@0000000000000000 PUBLIC _main EXTRN _memset:PROC ; COMDAT __real@4059000000000000 CONST SEGMENT __real@4059000000000000 DQ 04059000000000000r ; 100 CONST ENDS ; COMDAT __real@0000000000000000 CONST SEGMENT __real@0000000000000000 DQ 00000000000000000r ; 0 ; Function compile flags: /Ogtp CONST ENDS ; COMDAT _main _TEXT SEGMENT tv166 = -8 ; size = 8 _li$67108 = -8 ; size = 8 _li$67103 = -8 ; size = 8 _li$67098 = -8 ; size = 8 _durationMS$ = -8 ; size = 8 _argc$ = 8 ; size = 4 _argv$ = 12 ; size = 4 _main PROC ; COMDAT ; Line 136 push ebp mov ebp, esp and esp, -64 ; ffffffc0H sub esp, 52 ; 00000034H push ebx push esi push edi ; Line 140 push 100000000 ; 05f5e100H call DWORD PTR __imp__malloc add esp, 4 ; Line 141 push 100000000 ; 05f5e100H mov edi, eax push 0 push edi call _memset add esp, 12 ; 0000000cH ; Line 142 push 0 call DWORD PTR __imp___time64 add esp, 4 push eax call DWORD PTR __imp__srand mov ebx, DWORD PTR __imp__rand add esp, 4 xor esi, esi npad 7 $LL6@main: call ebx and eax, -2147483393 ; 800000ffH jns SHORT $LN21@main dec eax or eax, -256 ; ffffff00H inc eax $LN21@main: mov BYTE PTR [esi+edi], al inc esi cmp esi, 99999999 ; 05f5e0ffH jl SHORT $LL6@main ; Line 145 call ?createLookup@@YAXXZ ; createLookup ; Line 146 call ?createLookupWide@@YAXXZ ; createLookupWide ; Line 149 mov ebx, DWORD PTR __imp__QueryPerformanceFrequency@4 lea eax, DWORD PTR _li$67098[esp+64] push eax call ebx mov esi, DWORD PTR __imp__QueryPerformanceCounter@4 test eax, eax je SHORT $LN12@main fild QWORD PTR _li$67098[esp+64] lea ecx, DWORD PTR _li$67098[esp+64] push ecx fdiv QWORD PTR __real@408f400000000000 fstp QWORD PTR ?PCFreq@@3NA ; PCFreq call esi mov edx, DWORD PTR _li$67098[esp+64] mov eax, DWORD PTR _li$67098[esp+68] mov DWORD PTR ?CounterStart@@3_JA, edx mov DWORD PTR ?CounterStart@@3_JA+4, eax $LN12@main: ; Line 150 fld QWORD PTR ?PCFreq@@3NA ; PCFreq fldz fucompp fnstsw ax test ah, 68 ; 00000044H jp SHORT $LN1@main ; Line 152 push OFFSET ??_C@_0BD@ONNLNDEL@QPC?5did?5not?5work?4?4?$AA@ call DWORD PTR __imp__printf add esp, 4 ; Line 153 mov eax, 1 ; Line 171 pop edi pop esi pop ebx mov esp, ebp pop ebp ret 0 $LN1@main: ; Line 157 lea ecx, DWORD PTR _li$67103[esp+64] push ecx call ebx test eax, eax je SHORT $LN15@main fild QWORD PTR _li$67103[esp+64] lea edx, DWORD PTR _li$67103[esp+64] push edx fdiv QWORD PTR __real@408f400000000000 fstp QWORD PTR ?PCFreq@@3NA ; PCFreq call esi mov eax, DWORD PTR _li$67103[esp+64] mov ecx, DWORD PTR _li$67103[esp+68] mov DWORD PTR ?CounterStart@@3_JA, eax mov DWORD PTR ?CounterStart@@3_JA+4, ecx $LN15@main: ; Line 159 mov eax, edi call ?stringRotation@@YAXPAEH@Z ; stringRotation ; Line 161 lea edx, DWORD PTR _li$67108[esp+64] push edx call esi mov eax, DWORD PTR _li$67108[esp+64] sub eax, DWORD PTR ?CounterStart@@3_JA mov ecx, DWORD PTR _li$67108[esp+68] sbb ecx, DWORD PTR ?CounterStart@@3_JA+4 mov DWORD PTR tv166[esp+64], eax mov DWORD PTR tv166[esp+68], ecx fild QWORD PTR tv166[esp+64] ; Line 164 mov esi, DWORD PTR __imp__printf sub esp, 8 fdiv QWORD PTR ?PCFreq@@3NA ; PCFreq fst QWORD PTR _durationMS$[esp+72] fstp QWORD PTR [esp] push OFFSET ??_C@_0CF@MOIGNLJO@100?5Megabytes?5took?5?$CFf?5millisecon@ call esi ; Line 165 fld QWORD PTR __real@4059000000000000 fdiv QWORD PTR _durationMS$[esp+76] ; Line 166 add esp, 4 fmul QWORD PTR __real@408f400000000000 fstp QWORD PTR [esp] push OFFSET ??_C@_09IJINBEEB@MB?1s?5?$DN?5?$CFf?$AA@ call esi add esp, 12 ; 0000000cH ; Line 169 push edi call DWORD PTR __imp__free add esp, 4 ; Line 171 pop edi pop esi xor eax, eax pop ebx mov esp, ebp pop ebp ret 0 _main ENDP _TEXT ENDS END Edit: Kommenterte ut noe ubrukt kode i createLookupWide. Endret 30. september 2012 av Paull Lenke til kommentar
LonelyMan Skrevet 30. september 2012 Del Skrevet 30. september 2012 (endret) Du bruker fortsatt widechar her. Jeg vet ikke om du er klar over det men du poster assembler koden til meg og jeg har den rett foran nesa, er dette aprilspøk eller? Snakkes senere Endret 30. september 2012 av LonelyMan Lenke til kommentar
Paull Skrevet 30. september 2012 Del Skrevet 30. september 2012 Aprilspøk? Laget bare lookup-bufferet basert på 2 bytes istedet for 1: #include <Windows.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <time.h> double PCFreq = 0.0; __int64 CounterStart = 0; void StartCounter() { LARGE_INTEGER li; if(!QueryPerformanceFrequency(&li)) return; PCFreq = double(li.QuadPart)/1000.0; QueryPerformanceCounter(&li); CounterStart = li.QuadPart; } double GetCounter() { LARGE_INTEGER li; QueryPerformanceCounter(&li); return double(li.QuadPart-CounterStart)/PCFreq; } static char lookup[256]; static short lookupWide[65536]; static void randomStrGen(unsigned char *str, int length) { srand(time(NULL)); int i; for (i = 0; i < length; i++) str[i] = rand() % 256; } void stringRotation(unsigned char *text, int len) { int i; int tmp; short low; short high; int intLen = len / (sizeof(int) / sizeof(char)); for(i = 0; i < intLen; i++) { tmp = text[i]; low = (tmp & 0xFFFF); high = ((tmp >> 16) & 0xFFFF); text[i] = ((lookupWide[high] << 16 & 0xFFFF0000) | (lookupWide[low] & 0xFFFF)); } } void createLookup() { int c; for (c = 0; c < 256; c++) { lookup[c] = c; } for (c = 'A'; c <= 'Z' ; c++) { if (c <= 'M') { lookup[c] = c + 13; } else { lookup[c] = c - 13; } } for (c = 'a'; c <= 'z'; c++) { if (c <= 'm') { lookup[c] = c + 13; } else { lookup[c] = c - 13; } } } void createLookupWide() { char firstChar; char secondChar; short tmp = 0; for(int x = 0; x < 65536; x++) { firstChar = (x >> 8) & 0xFF; secondChar = (x & 0xFF); lookupWide[x] = ((lookup[firstChar] << 8) & 0x0000FF00) | (lookup[secondChar] & 0xFF); } } int main(int argc, char *argv[]) { // Build test string int size = 1000000 * 100; unsigned char *test = (unsigned char*) malloc(size); memset(test, 0, size); randomStrGen(test, size-1); // Build lookuptables createLookup(); createLookupWide(); // Test QPC StartCounter(); if(PCFreq == 0.0) { printf("QPC did not work.."); return 1; } // Start StartCounter(); stringRotation(test, size); double durationMS = GetCounter(); printf("100 Megabytes took %f milliseconds.\n", durationMS); double megabyterPerSec = (100.0/(durationMS)) * 1000.0; printf("MB/s = %f", megabyterPerSec); // Done free(test); return 0; } Lenke til kommentar
LonelyMan Skrevet 30. september 2012 Del Skrevet 30. september 2012 (endret) Paull, den leser fortsatt 25 millioner bytes og skriver fortsatt 25 millioner bytes, altså 1/4 av hva den skal gjøre. Jeg fatter ikke hvordan du kan gå fra 6 millisekunder til 14 millisekunder med den samme koden. Det er helt utrolig spør du meg. Den forandringen du gjorde med 52 bytes vs 256 har absolutt ingen effekt på koden du la frem nå, hvordan du gikk fra 6 til 14 ms er et data-under. Endret 30. september 2012 av LonelyMan Lenke til kommentar
Paull Skrevet 30. september 2012 Del Skrevet 30. september 2012 (endret) Ah, ja stemmer. Ser det blir galt der, caster char'en til en int istedet for å lese alle 4 bytene av inten. Endret 30. september 2012 av Paull Lenke til kommentar
LonelyMan Skrevet 30. september 2012 Del Skrevet 30. september 2012 (endret) Nei den leser ikke ints, den leser bytes. Den caster en byte til en int, og dermed leser du en fjerdedel av bufferen. I c++ koden din er det vanskelig å se det, men i assembler koden er det absolutt åpenbart. Her caster den: tmp = text[i]; Det er veldig lett å gjøre feil i kodingen så det gjør ingenting, lov å skrive feil. Jeg forsøker på ingen måte å være bombastisk her, jeg er bare dønn ærlig og sier ting som de er. Jeg er bare nødt å peke ut dette, for det er en grov feil. Jeg har gjort mange slike feil i høynivåspråk, ting er så kompakt i høynivåspråk at det er lett å overse en bagatell. I assembler så virker nesten ingenting av koden om noe er feil så der er det lett å gjøre ting riktig, hvis noe ikke er riktig så er sjansen stor for at ingenting fungerer i det hele tatt. Endret 30. september 2012 av LonelyMan Lenke til kommentar
jonny Skrevet 30. september 2012 Del Skrevet 30. september 2012 (endret) Jeg fikk ikke koden til Paull til å gjøre roteringa raskere på min prosessor, men benyttet meg av hans idé om å bruke en 16-bits lookup-table med følgende kode: void stringRotation2(unsigned char *text, int len) { int align_offset = (unsigned long)text % UL_SIZE; int i = 0; if (align_offset > 0) { for (; i < UL_SIZE - align_offset; i++) { int tmp = text[i]; text[i] = lookup[tmp]; } } if (UL_SIZE == 8) { for (; i <= len - UL_SIZE; i += UL_SIZE) { unsigned long *bytesPtr = (unsigned long *)&text[i]; unsigned long oldval = *bytesPtr; unsigned long newval = lookups[oldval & 0xffff]; oldval >>= 16; newval |= (unsigned long)(lookups[oldval & 0xffff]) << 16; oldval >>= 16; newval |= (unsigned long)(lookups[oldval & 0xffff]) << 32; oldval >>= 16; newval |= (unsigned long)(lookups[oldval & 0xffff]) << 48; *bytesPtr = newval; } } else if (UL_SIZE == 4) { for (; i <= len - UL_SIZE; i += UL_SIZE) { unsigned long *bytesPtr = (unsigned long *)&text[i]; unsigned long oldval = *bytesPtr; unsigned long newval = lookups[oldval & 0xffff]; oldval >>= 16; newval |= (unsigned long)(lookups[oldval & 0xffff]) << 16; *bytesPtr = newval; } } for (; i < len; i++) { int tmp = text[i]; text[i] = lookup[tmp]; } } Denne funksjonen blir ferdig ila. 60 ms på min prosessor (lookups er 16-bit-lookup-tabellen). Endret 30. september 2012 av jonny Lenke til kommentar
Drogin Skrevet 1. oktober 2012 Del Skrevet 1. oktober 2012 (endret) Har ikke fulgt helt med i denne debatten i det siste, men virker som dere har begynt å sammenlikne algoritmer og datastrukturer, og ikke compilerns arbeid vs "manuell assembler" Endret 1. oktober 2012 av Drogin Lenke til kommentar
LonelyMan Skrevet 1. oktober 2012 Del Skrevet 1. oktober 2012 (endret) Laget en simulator for å se tiden det tar å vinne i lotto. Nå bruker jeg pseudo random algoritme, det er den eneste svakheten og jeg har laget en delay bare for underholdningens skyld. Lotto.rar Endret 1. oktober 2012 av LonelyMan Lenke til kommentar
Antoweif Skrevet 1. oktober 2012 Del Skrevet 1. oktober 2012 Og den onde sannheten er at jeg nå har spilt 10000 uker og enda ikke fått 7 rette Lenke til kommentar
LonelyMan Skrevet 1. oktober 2012 Del Skrevet 1. oktober 2012 (endret) Antoweif, norsk tipping sine egne nettsider sier følgende om 7 rette: "I teorien kan man si at det er bortimot umulig å få sju rette, men på den annen side er det i gjennomsnitt fire personer som opplever dette hver eneste lørdag." Når ukene i programmet når 500 tusen uker, så vil det si at den norske befolkningen har spilt èn gang, men for deg vil det si at du har spilt 500 tusen ganger. Det er ca 500k spillere i Norge. Endret 1. oktober 2012 av LonelyMan Lenke til kommentar
jonny Skrevet 1. oktober 2012 Del Skrevet 1. oktober 2012 Når det gjelder hvor raskt en kan skrive i assembly, så skal en heller ikke undervurdere det, der er mange direktiver og makroinstruksjoner som gjør ting ekstremt effektivt. Dette nibbles spillet jeg legger vedlagt har jeg skrevet på en dag. Det er ikke ferdig, og det er kun første level (ingen vegger på første level) Den er skrevet for 4 kjerner prosessorer og bør kjøres på en slik cpu. Last ned hvis du vil teste. Skrevet i helt ren assembler. Det hadde ikke vært nødvendig å bruke 4 kjerner da spillet er så lite krevende. Men det har betydning på keyboard polling. 1 kjerne rendererer grafikk 2 kjerne trekker taster fra tastaturet 3 kjerne genererer random tall for plassering av matbiter 4 kjerne genererer høypresisjons game-tick Virker som 2 kjerner brukes 100% kontinuerlig. Bevegelsen til ormen er heller ikke glatte, den rykker litt nå og da. Men ganske artig Lenke til kommentar
LonelyMan Skrevet 1. oktober 2012 Del Skrevet 1. oktober 2012 (endret) En kjerne kjører keyboard polling kontinuerlig så den vil ha høy load, den andre genererer ticks hvert millisekund og vil også ha høy load, men ikke like mye som keyboard pollingen. De to andre vil ha lav load. Når det gjelder hakkingen så er det noe feil med tick-synkroniseringen som gjør at tiden akkumulerer opp over en viss tid og genererer et tick for mye. Antar jeg. Dette er GDI dog, ikke direct3d. Jeg har laget et nibbles spill i direct3d også, men det er i høynivåspråk, og den har funny grafikk i motsetning til denne jeg laget nå. Lurer på om den ennå hakker av og til? Nibbles.rar Endret 1. oktober 2012 av LonelyMan Lenke til kommentar
jonny Skrevet 1. oktober 2012 Del Skrevet 1. oktober 2012 Jeg merker ingen forskjell fra den forrige versjonen av programmet. Er litt ujevn hastighet på slangen (den beveger seg jo ganske raskt, som sikkert gjør det lettere å oppdage små unøyaktigheter). Lenke til kommentar
LonelyMan Skrevet 1. oktober 2012 Del Skrevet 1. oktober 2012 Forandret litt av koden, tror den er bedre nå. Nibbles.rar Lenke til kommentar
GeirGrusom Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 Det er ikke noe poeng å ha en egen tråd for å pollle tastaturet: ikke les inn data du ikke har tenkt til å bruke. Istedet for en egen tick tråd, så kan du istedet bare regne ut delta-tid fra forrige frame-tick og bruke det som en multiplikator for hvor mye verden skal bevege seg. Dette kan du da lett bruke for å også legge ut epler. Da vil du sitte igjen med to tråder. Lenke til kommentar
Kanutus Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 Hva med assembly på iPhone? Er det en mulighet? Hadde vært kult, ja ... Tviler litt, dog, da Apple trolig ikke vil slippe folk inn på for nært. Er det ikke slik at man ikke engang vet specs på den nyeste prosessoren de bruker? Lenke til kommentar
LonelyMan Skrevet 2. oktober 2012 Del Skrevet 2. oktober 2012 (endret) Om du bruker delta tiden så må du bruke performance counters, og denne delta tiden vil før eller senere føre til et at det blir et frame for mye eller for lite. Det fungerer bra i et 3d spill hvor du roterer verden for der vil du ikke merke denne frame-kickingen, og de fleste spill er 3d spill nå om dagene. Men i nibbles som dette jeg har laget så må du unngå delta timing. Istedet for å bruke delta så kan du utnytte "naturlovene" i datamaskinen slik at den tiden det tar å kjøre koden akkumulerer opp slik at timingen BLIR den tiden du behøver uansett, uten å kalkulere delta tiden. F.eks når du skal time en bit av koden din for å se hvor raskt den kjører, så kjører du kanskje slik: TimeStart Kjør kode TimeSlutt API funksjonen du bruker for start har også en viss kjøretid, ikke mye, men den har litt. Men det har også slutt api funksjonen også. om TimeStart hypotetisk sett kjører på 50 mikrosekunder og TimeSlutt også kjører på 50 mikrosekunder, så ender du opp uten å måtte kalkulere delta tid uansett. for 50 + x + 50 så ender du opp med samme tiden du behøver. Det er bedre å la systemet ta seg av delta på en naturlig måte. Når det gjelder keyboard pollingen så BEHØVER jeg ikke å kjøre i en egen tråd som jeg sa tidligere jeg hadde ikke behøvd å kjøre 4 tråder med nibbles. Men det har likevel effekt på keyboard pollingen. Det eneste unntaket er hvis jeg bruker rawinput eller directinput. Jeg har skrevet rutiner for å bruke rawinput, men jeg orker ikke legge det inn. Om du skal bruke vanlige windows beskjeder for å handle keyboard så kjøres beskjedene lineært, og problemet med å handle keyboard polling lineært er at om den som spiller ombestemmer tastetrykket sitt før ormen har snudd seg, så vil det oppstå et mikrosekunds feil slik at ormen ikke snur seg likevel. Fordi rendereringen og handlingen av ormen tar litt tid å kjøre, det er ikke slik at du ikke rekker å trykke om du ikke brukte en egen tråd, men det jeg sier er at om brukeren trykker en annen tast så vil han med et uhell ville oppleve å miste tastetrykket sitt iblant, og dette uhellet oppleves i spillet, men ikke nå når jeg kjører pollingen i egen tråd. Lettere å forklare med punkter: 1. Ormen beveges og rendereres (noe pre-code kjører for å forberede dette) 2. Koden har forberedt bevegelser og er nå ready for å lese keyboard pollingen 3. brukeren trykket ny retning og den nye retningen er registrert 4. koden beveger ormen Det er vanskelig å forstå, men tastetrykk for ormen er meget kompleks, selv om det er et enkelt spill, og denne kompleksiteten gjør det bedre å kjøre i egen tråd. Jeg kunne forklart hvordan tastetrykkene fungerer, men litt senere. Om du likevel ikke skulle brukt egen tråd til dette og bare polle tastetrykket idet du rendererer og tegner ormen, så ville du på lik linje mistet noen mikrosekunders FORTID. Og samme problemet oppstår. Endret 2. oktober 2012 av LonelyMan 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å