Devadesátková hra Brány Skeldalu prošla portací a je dostupná na platformě Steam. Vyšel i parádní blog autora o portaci na moderní systémy a platformy včetně Linuxu.
Lidi dělají divné věci. Například spouští Linux v Excelu. Využít je emulátor RISC-V mini-rv32ima sestavený jako knihovna DLL, která je volaná z makra VBA (Visual Basic for Applications).
Revolut nabídne neomezený mobilní tarif za 12,50 eur (312 Kč). Aktuálně startuje ve Velké Británii a Německu.
Společnost Amazon miliardáře Jeffa Bezose vypustila na oběžnou dráhu první várku družic svého projektu Kuiper, který má z vesmíru poskytovat vysokorychlostní internetové připojení po celém světě a snažit se konkurovat nyní dominantnímu Starlinku nejbohatšího muže planety Elona Muska.
Poslední aktualizací začal model GPT-4o uživatelům příliš podlézat. OpenAI jej tak vrátila k předchozí verzi.
Google Chrome 136 byl prohlášen za stabilní. Nejnovější stabilní verze 136.0.7103.59 přináší řadu novinek z hlediska uživatelů i vývojářů. Podrobný přehled v poznámkách k vydání. Opraveno bylo 8 bezpečnostních chyb. Vylepšeny byly také nástroje pro vývojáře.
Homebrew (Wikipedie), správce balíčků pro macOS a od verze 2.0.0 také pro Linux, byl vydán ve verzi 4.5.0. Na stránce Homebrew Formulae lze procházet seznamem balíčků. K dispozici jsou také různé statistiky.
Byl vydán Mozilla Firefox 138.0. Přehled novinek v poznámkách k vydání a poznámkách k vydání pro vývojáře. Řešeny jsou rovněž bezpečnostní chyby. Nový Firefox 138 je již k dispozici také na Flathubu a Snapcraftu.
Šestnáctý ročník ne-konference jOpenSpace se koná 3. – 5. října 2025 v Hotelu Antoň v Telči. Pro účast je potřeba vyplnit registrační formulář. Ne-konference neznamená, že se organizátorům nechce připravovat program, ale naopak dává prostor všem pozvaným, aby si program sami složili z toho nejzajímavějšího, čím se v poslední době zabývají nebo co je oslovilo. Obsah, který vytvářejí všichni účastníci, se skládá z desetiminutových
… více »Bohužel, GCC je všemocné a i ten assembler umí lépe než já. Ve svém programu potřebuji převádět čísla na řetězce (až 99999999 krát v cyklu). Řetězec musí bít zarovnané vpravo v poli zaků (velikost 8) a obsahovat úvodní nuly, pokud je kratší než 8.
Nejprve jsem použil funkci sprintf(), jenže můj algoritmus byl příliš pomalý - funkce je příliš mocná a tedy i pomalá k takovémuto účelu. Napsal jsem si tedy vlastní funkci a najivně jsem použil inline assembler, že když už to píšu, tak to napíšu nejlépe, jak dokážu. Toto jsem napsal:
void IntToStr8(uint32_t num, char* str) { asm volatile( "mov $10, %%ecx\n" "mov %1, %%eax\n" "xor %%edx, %%edx\n" "div %%ecx\n" "add $0x30, %%edx\n" "movb %%dl, 7(%0)\n" "xor %%edx, %%edx\n" "div %%ecx\n" "add $0x30, %%edx\n" "movb %%dl, 6(%0)\n" "xor %%edx, %%edx\n" "div %%ecx\n" "add $0x30, %%edx\n" "movb %%dl, 5(%0)\n" "xor %%edx, %%edx\n" "div %%ecx\n" "add $0x30, %%edx\n" "movb %%dl, 4(%0)\n" "xor %%edx, %%edx\n" "div %%ecx\n" "add $0x30, %%edx\n" "movb %%dl, 3(%0)\n" "xor %%edx, %%edx\n" "div %%ecx\n" "add $0x30, %%edx\n" "movb %%dl, 2(%0)\n" "xor %%edx, %%edx\n" "div %%ecx\n" "add $0x30, %%edx\n" "movb %%dl, 1(%0)\n" "xor %%edx, %%edx\n" "div %%ecx\n" "add $0x30, %%edx\n" "movb %%dl, (%0)\n" : : "r"(str), "r"(num) : "%eax", "%ecx", "%edx" ); }
Pro přehlednost ještě v Intel syntax z objdumpu:
;;;;; IntToStr8 ;;;;; Input edi = number, rsi = char[8] 405930: b9 0a 00 00 00 mov ecx,0xa 405935: 89 f8 mov eax,edi 405937: 31 d2 xor edx,edx 405939: f7 f1 div ecx 40593b: 83 c2 30 add edx,0x30 40593e: 88 56 07 mov BYTE PTR [rsi+0x7],dl 405941: 31 d2 xor edx,edx 405943: f7 f1 div ecx 405945: 83 c2 30 add edx,0x30 405948: 88 56 06 mov BYTE PTR [rsi+0x6],dl 40594b: 31 d2 xor edx,edx 40594d: f7 f1 div ecx 40594f: 83 c2 30 add edx,0x30 405952: 88 56 05 mov BYTE PTR [rsi+0x5],dl 405955: 31 d2 xor edx,edx 405957: f7 f1 div ecx 405959: 83 c2 30 add edx,0x30 40595c: 88 56 04 mov BYTE PTR [rsi+0x4],dl 40595f: 31 d2 xor edx,edx 405961: f7 f1 div ecx 405963: 83 c2 30 add edx,0x30 405966: 88 56 03 mov BYTE PTR [rsi+0x3],dl 405969: 31 d2 xor edx,edx 40596b: f7 f1 div ecx 40596d: 83 c2 30 add edx,0x30 405970: 88 56 02 mov BYTE PTR [rsi+0x2],dl 405973: 31 d2 xor edx,edx 405975: f7 f1 div ecx 405977: 83 c2 30 add edx,0x30 40597a: 88 56 01 mov BYTE PTR [rsi+0x1],dl 40597d: 31 d2 xor edx,edx 40597f: f7 f1 div ecx 405981: 83 c2 30 add edx,0x30 405984: 88 16 mov BYTE PTR [rsi],dl 405986: c3 ret
Čas běhu mého algoritmu se zkrátil z 31s na 24s. Docela slušné, říkal jsem si. Jen tak ze zvědavosti jsem si však zkusil napsat něco přímo v C a vyzkoušet rychlost.
void IntToStr8(uint32_t num, char* str) { uint32_t rem; rem = num % 10; str[7] = (char)(unsigned char)(rem + 0x30); num /= 10; rem = num % 10; str[6] = (char)(unsigned char)(rem + 0x30); num /= 10; rem = num % 10; str[5] = (char)(unsigned char)(rem + 0x30); num /= 10; rem = num % 10; str[4] = (char)(unsigned char)(rem + 0x30); num /= 10; rem = num % 10; str[3] = (char)(unsigned char)(rem + 0x30); num /= 10; rem = num % 10; str[2] = (char)(unsigned char)(rem + 0x30); num /= 10; rem = num % 10; str[1] = (char)(unsigned char)(rem + 0x30); num /= 10; rem = num % 10; str[0] = (char)(unsigned char)(rem + 0x30); }
GCC vygenerovalo toto:
;;;;; IntToStr8 - GCC from C++ code ;;;;; Input edi = number, rsi = char[8] 405930: b9 cd cc cc cc mov ecx,0xcccccccd 405935: 89 f8 mov eax,edi 405937: f7 e1 mul ecx 405939: 41 89 d1 mov r9d,edx 40593c: 41 c1 e9 03 shr r9d,0x3 405940: 43 8d 04 89 lea eax,[r9+r9*4] 405944: 01 c0 add eax,eax 405946: 29 c7 sub edi,eax 405948: 44 89 c8 mov eax,r9d 40594b: f7 e1 mul ecx 40594d: 83 c7 30 add edi,0x30 405950: 40 88 7e 07 mov BYTE PTR [rsi+0x7],dil 405954: 41 89 d0 mov r8d,edx 405957: 41 c1 e8 03 shr r8d,0x3 40595b: 43 8d 04 80 lea eax,[r8+r8*4] 40595f: 01 c0 add eax,eax 405961: 41 29 c1 sub r9d,eax 405964: 44 89 c0 mov eax,r8d 405967: f7 e1 mul ecx 405969: 41 83 c1 30 add r9d,0x30 40596d: 44 88 4e 06 mov BYTE PTR [rsi+0x6],r9b 405971: 89 d7 mov edi,edx 405973: c1 ef 03 shr edi,0x3 405976: 8d 04 bf lea eax,[rdi+rdi*4] 405979: 01 c0 add eax,eax 40597b: 41 29 c0 sub r8d,eax 40597e: 89 f8 mov eax,edi 405980: f7 e1 mul ecx 405982: 41 83 c0 30 add r8d,0x30 405986: 44 88 46 05 mov BYTE PTR [rsi+0x5],r8b 40598a: 41 89 d0 mov r8d,edx 40598d: 41 c1 e8 03 shr r8d,0x3 405991: 43 8d 04 80 lea eax,[r8+r8*4] 405995: 01 c0 add eax,eax 405997: 29 c7 sub edi,eax 405999: 44 89 c0 mov eax,r8d 40599c: f7 e1 mul ecx 40599e: 83 c7 30 add edi,0x30 4059a1: 40 88 7e 04 mov BYTE PTR [rsi+0x4],dil 4059a5: 89 d7 mov edi,edx 4059a7: c1 ef 03 shr edi,0x3 4059aa: 8d 04 bf lea eax,[rdi+rdi*4] 4059ad: 01 c0 add eax,eax 4059af: 41 29 c0 sub r8d,eax 4059b2: 89 f8 mov eax,edi 4059b4: f7 e1 mul ecx 4059b6: 41 83 c0 30 add r8d,0x30 4059ba: 44 88 46 03 mov BYTE PTR [rsi+0x3],r8b 4059be: 41 89 d0 mov r8d,edx 4059c1: 41 c1 e8 03 shr r8d,0x3 4059c5: 43 8d 04 80 lea eax,[r8+r8*4] 4059c9: 01 c0 add eax,eax 4059cb: 29 c7 sub edi,eax 4059cd: 44 89 c0 mov eax,r8d 4059d0: f7 e1 mul ecx 4059d2: 83 c7 30 add edi,0x30 4059d5: 40 88 7e 02 mov BYTE PTR [rsi+0x2],dil 4059d9: 89 d7 mov edi,edx 4059db: c1 ef 03 shr edi,0x3 4059de: 8d 04 bf lea eax,[rdi+rdi*4] 4059e1: 01 c0 add eax,eax 4059e3: 41 29 c0 sub r8d,eax 4059e6: 89 f8 mov eax,edi 4059e8: f7 e1 mul ecx 4059ea: 41 83 c0 30 add r8d,0x30 4059ee: 44 88 46 01 mov BYTE PTR [rsi+0x1],r8b 4059f2: c1 ea 03 shr edx,0x3 4059f5: 8d 14 92 lea edx,[rdx+rdx*4] 4059f8: 01 d2 add edx,edx 4059fa: 29 d7 sub edi,edx 4059fc: 83 c7 30 add edi,0x30 4059ff: 40 88 3e mov BYTE PTR [rsi],dil 405a02: c3 retO poznání delší (a hnusnější) vygenerovaný kód. Jaké bylo mé překvapení, když se čas běhu algoritmu byl 19s. Ty x86-* procesory jsou asi nějaký šmejďárny, když mají takové pomalé dělení ...
Tiskni
Sdílej:
for (uint32_t j = 0; j < 10; ++j) { for (i = 0; i <= 99999999u; ++i) { IntToStr8(i, pwd); } }V případě C funkce 19s, v případě mé funkce v assembleru 2m4s a při použití sprintf() 3m48s. A to se opravdu vyplatí
void IntToStr8(uint32_t num, char* str) { uint32_t rem; for (int i=7;i>=0;i--) { rem=num%10; str[i]=(char)(unsigned char)(rem + 0x30); num /= 10; } }
Takový DMA by musel počítat s tím, že souvislý blok paměti z heldiska procesu není souvislý blok ve fyzické paměti.To je fakt, granularita po stránkách ujde. Jinak scatter gather.
Dále by DMA musel počítat s tím, že fyzická paměť dokonce vůbec nemusí existovat, ale může být ve swapu.To je fakt. Ale to je stejný jako u memcpy imho.
Dále DMA může umět zapsat někam, kde to proces nemá povoleno.Tak to je na OS
Nevěřte tomu, že by 1KB DMA byl obecně rychlejší. Se vším tím servisem kolem by zoufale zaostával.Tak samozřejmě musely by být nějaký semafory apod. Ale je celkem blbý v době, kdy probíhá po světě paralelizace úloh kopírovat celým jádrem bajt po bajtu. Jinak ten kilobajt jsem prostě jen tak nadhodil, klidně to může být ona stránka. Ale je fakt škoda, že DMA neumí spolupracovat s MMU
Právě že zas tak moc ne, protože když DMA obejde CPU, tak si toho OS prostě nevšimneMyslel jsem to tak, že by měl OS vědět kam se může zapisovat a kam ne a tedy znát, že celej rozsah je validní a lze do něj zapisovat. Jinak třeba na takovým OMAPu se používá DMA na triviality jako rotace bitmapy.
nebo by se to DMA muselo používat jako volání OS, nikoli jako funkce v programu.To tak ale obvykle bývá, že když využíváš nějaké zařízení, používáš k tomu volání jádra. (Další zdroj zdržení a důvod dělat to rovnou.)
ARM jádro pracuje s pamětí setsakra blbě a setsakra pomalu. Jeho RISCová architektura typu load/store potřebuje třeba i několik instrukcí na paměťovou operaci ve strojáku na to, co x86 dokáže často jednou instrukcí.... až na to, že těch i několik instrukcí zvládne provést rychleji než odpovídající x86. To, že odpovídající x86 je dneska zastaralá šunka, je důsledek faktu, že x86 má mnoholetý náskok ve vývoji (než se zjistilo, že pro mobilní stroje apod. se x86 nechytá a že to chce něco jiného - efektivnějšího.)
x86 je jiná architektura, navíc na ní jsou provozovány chytřejší operační systémy, které počítají se stránkováním, ochranou pamětiPoužívání ARM nic takového nevylučuje.
U ARMu je to z hlediska jádra cpu externí součást, kterou neřídí a nezná o ní přímo podrobnosti.[citation needed] Nebo jinak - co je podle tebe externí součást? Čip o kousek vedle procesoru? Kdy žiješ? A btw. i kdyby to tak bylo, nic to nemění na tom, že bude fungovat stránkování, ochrana paměti atd.
x86 je jiná architektura, navíc na ní jsou provozovány chytřejší operační systémy, které počítají se stránkováním, ochranou paměti, swapováním a ochranou procesů mezi sebou.No já nevím, thumb módy v ARMu jsou imho dost velkej hi-tech
co x86 dokáže často jednou instrukcíI po rozložení do vlastního mikrokódu? Já si osobně myslím, že DMA by šla pro memcpy použít a i přes náročný servis by to pro tisíce bajtů bylo větší zrychlení, i když možná jen pro speciální případy. Kopírování textu do konzole uživateli stačí imho bit po bitu
BTW takový multimedia taky mají svojí podporu v CPU.To jo, ale to už je trochu něco jiného. U multimediálních instrukcí je to použít nejstarší x86 instrukce a dělat něco dlouho vs. použít mutimediální instrukce a dělat to rychleji. U kopírování pomocí DMA chceš kopírovat pomocí DMA enginu a zároveň dělat něco jiného. V tom prvním případě se mění jenom to, jak něco děláš z hlediska instrukční sady. V tom druhém se pokoušíš paralelizovat něco, co dost dobře paralelizovat nejde (viz. ten kus kódu níže), tzn. v praxi by ti stejně nezbylo nic jiného, než během kopírování buď čekat*, nebo zpracovávat úplně jinou úlohu (nevýhody jsem popisoval jinde) * tohle by mohlo mít smysl třeba v případě, že bychom chtěli šetřit energii. Během kopírování by se CPU přepnul do nějakého úsporného režimu (malá úspora, rychlé probuzení) a kopírování by zajistil na energii méně náročnější DMA engine. I v tomhle případě bych ale řekl, že by bylo jednodušší prostě umožnit uspávání těch částí CPU, které se při kopírování nevyužijí. I když tady se zase objevují záležitosti typu jak poznat, že teď je možné se uspat atd.
a = cekej_na_nejaka_data_a_vrat_na_ne_ukazatel(); b = dej_mi_ukazatel_na_cilovy_blok(); c = rekni_mi_kolik_bytu_mam_kopirovat(); memcpy(b, a, c); // implementováno neblokující instrukcí, která používá DMA udelej_neco_s_daty_v_bloku(b);Ještě mě napadlo, že vlastně by ten příklad šel i s DMA, například pokud by bylo vyžadováno malé latence, ale vyžadovalo by to paralelnější přístup k kódu. Ta memcpy totiž pro určité funkce udelej_neco_s_daty_v_bloku() nemusí nutně kopírovat celý béčko. Pokud by zkopírovala jen třeba prvních 64bajtů, tak by se během dalšího přenosu 64bajtů mohlo současně zpracovávat tou funkcí těch prvních 64B. Což by ve výsledku mohlo znamenat třeba i dvojnásobný zrychlení.
To je fakt. Ale to je stejný jako u memcpy imho.Není (a Gilhad v #40 o kousek vejš nemá pravdu). Memcpy běží v userspace, takže když se pokusí sáhnout na paměť, která je zrovna odswapovaná, CPU hodí výjimku, jádro ji chytí, stránku někam nahraje a pak se program nechá běžet dál. Nic takového, jako že by memcpy po bytech kontrolovala, jestli nedošlo k výpadku paměti, se neděje. Dokonce AFAIK ani nemůže (proces neví, které jeho stránky v paměti jsou a které ne)
Tak samozřejmě musely by být nějaký semafory apod.Hádám, že servisem je myšleno nastavit to DMA zařízení atd. To bude trvat relativně dlouho (I/O), dost dlouho na to, aby se vyplatilo udělat to přímo.
Ale je celkem blbý v době, kdy probíhá po světě paralelizace úloh kopírovat celým jádrem bajt po bajtu.a) nevim, kde jste přišli na to byte po bytu. Na moderních procesorech to pravděpodobně bude v o něco větších kusech. b) klidně můžeš udělat paralelní kopírování. Nastavení vláken a jejich vzájemné čekání atd. atp., zkrátka to zase bude trvat déle než to zkopírovat sériově jedním CPU.
Není (a Gilhad v #40 o kousek vejš nemá pravdu). Memcpy běží v userspace, takže když se pokusí sáhnout na paměť, která je zrovna odswapovaná, CPU hodí výjimku, jádro ji chytí, stránku někam nahraje a pak se program nechá běžet dál.Tak by se před inicializací provedl test dané stránky zda existuje na určeném místě a případně jí natáhl ze swapu (btw už to samotný natažení ze swapu pravděpodobně koná DMA).
Nic takového, jako že by memcpy po bytech kontrolovala, jestli nedošlo k výpadku paměti, se neděje. Dokonce AFAIK ani nemůže (proces neví, které jeho stránky v paměti jsou a které ne)Jo to mě trochu zmátlo...
Hádám, že servisem je myšleno nastavit to DMA zařízení atd. To bude trvat relativně dlouho (I/O), dost dlouho na to, aby se vyplatilo udělat to přímo.Tak na x86 asi jo, někde jinde nemusí
a) nevim, kde jste přišli na to byte po bytu. Na moderních procesorech to pravděpodobně bude v o něco větších kusech.To byla nadsázka, ale klidně můžeš nahradit bajt skalárem a bude to mít stejnej význam. Právě jsem myslel, že by se hodilo v tomhle případě pracovat s vektorem. Teoreticky by šla substituovat současná instrukce REP MOVSD na nějakej triviální automat skalárního kopírování, pro program by se to jevilo jako vektor.
b) klidně můžeš udělat paralelní kopírování. Nastavení vláken a jejich vzájemné čekání atd. atp., zkrátka to zase bude trvat déle než to zkopírovat sériově jedním CPU.Jj, ale to dneska znamená plýtvat ALU jednoho jádra na kopírování, při DMA by byl celý ALU k dispozici a mohl třeba Jardíkovi louskat md5
Třeba na tom Vámi zmiňovaném ARMu je rychlost I/O katastrofa. I/O je tam realizováno mapováním do paměti.Fuj, radši pomalejší zápis do MMIO než používání brutálně neflexibilního IN/OUT na x86, navíc když to fyzicky používá tak jako tak stejný adresní dráty do procesoru. Věci jako MMU na IO je pak pozitivní vedlejší produkt. Programování I/O ve stylu 8bit je humus. Typově třeba uart řadič na způsob tady je registr na vysílaný bajt, ale pokud je v tom a tom registru v tom a tom bitu tahle hodnoa, tak to je nastavení děličky hodin, ale jen jedna polovina, druhá polovina (8bit) je zase v jiným registru, kterým se jinak ovládá něco jinýho. Když pak člověk pracuje třeba v 32bit prostředí a má 32bit registry, tak si rve vlasy proč to prostě nemohli dát do 32bit registru, kde by dělička měla rezervu na tisíc let dopředu
Nedělejte si iluze, x86 je hodně nalepovák, ale z hlediska výkonu je to excelentně dobrá architektura.No moje priority jsou: nalepovák → určitě ne nejlepší řešení.
Není to tak dávno, kdy se řada odpůrců těšila na to, že x86 architektura a celé CISC půjde do háje z důvodů nedostatečného výkonu. Nakonec se ukázalo, že právě univerzalita a vysokoúrovňovost x86 strojáku je mocná zbraň pro dosahování výkonu.To spíš kvůli vendor lock-inu.
Na x86 architektuře klidně můžete mít I/O mapované do paměti. Naprosto nic tomu nebrání. A také se to v řadě případů dělá.Takže tu je IN/OUT a ještě MOV? teda dva různé cykly generované chipsetu. To je ještě horší
Nebo si pročtěte v manuálu kolik taktů hodin u ARMu trvá reakce na přerušení. Budete zvracet. Když ARM na FIQ (fast interrupt request) zareaguje do 30 taktů hodin, jste zhruba na nejnižší možné hodnotě zpoždění.To bude hlavně kvůli tomu, že má každý blok vlastní hodiny ne? BTW v manuálu OMAP3 je u interrupt latency hodnota 10 (ale je možný se se ještě někde nabere). Jinak já mám Duron 600MHz a stačí mě to. Mě o nějaké latence přerušení fakt nejde. Za to mě jde třeba o dokumentaci čipu, takový zamknutý násobiče u Intelu je fakt opruz.
V tom případě si ARM také rovnou škrtněte. ARM je poměrně dosti nalepen.Ale já nechci škrtat. Jen v případě nalepováku se prostě sníží priorita meho zájmu.
Jestli si myslíte, že budete mít někdy architekturu starou 20 let a nebude v ní hafo nalepováků, tak jste naivní.S tím počítám.
Není to tak dávno, kdy se řada odpůrců těšila na to, že x86 architektura a celé CISC půjde do háje z důvodů nedostatečného výkonu. Nakonec se ukázalo,...že když x86 převezme nějaké myšlenky RISC architektury, že může existovat dál. Což se stalo asi tak před pěti - deseti lety. Hlavní výhoda RISC architektur je v tom, že má sice jednoduché instrukce, takže na stejnou věc jich je potřeba víc, ale ty instrukce se vykonávají mnohem rychleji, takže celkově je ten procesor podstatně rychlejší. Mimo jiné, srovnávat dnešní ARM s dnešními x86 není úplně fér, protože x86 se přece jenom vyvíjelo déle. A krom toho - kdyby x86 uměla všechno, co je potřeba, ARM by nikdo nepoužíval. Vývoj není zadarmo, přesto se ARM vyvíjí a používá, což nějaký důvod asi mít bude.
A krom toho - kdyby x86 uměla všechno, co je potřeba, ARM by nikdo nepoužíval. Vývoj není zadarmo, přesto se ARM vyvíjí a používá, což nějaký důvod asi mít bude.+1 a vendor lockin, nezapomínej na vendor lockin
Ale nenechte se realitou nikterak zneklidnit.... říká astrolog, co tu nedávno tvrdil, že dělení na FPU je rychlejší než pomocí SSE2 a trvá jeden tik hodin. (Nebo tak nějak to bylo, že?)
Je se to v praxi nepotvrzuje, takový drobný detail.V praxi se to potvrdilo velmi dobře, třeba v době, kdy ještě byly peníze na vývoj (řekněme rok '95), PowerPC naprosto válcovalo x86. Co se výkonu týče, x86 bylo za PowerPC opožděno o nějaké dva až tři roky. Ano, svět x86 nakonec to zpoždění dohnal, jenže ne díky CISC architektuře, ale díky tomu, že jistý majoritní OS PowerPC nepodporoval, takže trh s těmito CPU byl menší a tím bylo i míň peněz na vývoj.
Ano, svět x86 nakonec to zpoždění dohnal, jenže ne díky CISC architektuře, ale díky tomu, že jistý majoritní OS PowerPC nepodporoval, takže trh s těmito CPU byl menší a tím bylo i míň peněz na vývoj.
Není to hlavně tím, že x86 CPU jsou od jisté doby uvnitř RISCové? Pokud se pamatuji, tak uvnitř se dělá překlad x86 instrukcí na RISCové. Tedy aspoň to tak výrobci prezentovali.
Není to hlavně tím, že x86 CPU jsou od jisté doby uvnitř RISCové?Viz první odstavec v #58 (o kousek výš)
V praxi se to potvrdilo velmi dobře, třeba v době, kdy ještě byly peníze na vývoj (řekněme rok '95), PowerPC naprosto válcovalo x86. Co se výkonu týče, x86 bylo za PowerPC opožděno o nějaké dva až tři roky.Ono je to vidět i nedávno/dnes. Viz třeba obliba PS3 s Cellem.
Ono je to vidět i nedávno/dnes.A nejenom na "velkých" procesorech typu x86... u malých jednočipů to platí úplně stejně
Nicméně v absolutním výkonu ARM nemůže x86 konkurovat.Jo, tady se projevuje ten několikaletý náskok ve vývoji.
Znovu zdůrazňuji, ARM instrukce jsou pomaleji vykonávány, než x86 instrukce a to přesto, že x86 instrukce nahradí často několik ARM.Jestli to náhodou trochu nesouvisí s tím, že ARM CPU bývají taktovány na ~500MHz, kdežto x86 na 2GHz a více.
V neposlední řadě do vývoje a zdokonalování x86 byly vraženy takové prachy, jaké ARM mít nikdy nebude.Hvězdy promluvily...
Jestli to náhodou trochu nesouvisí s tím, že ARM CPU bývají taktovány na ~500MHz, kdežto x86 na 2GHz a více.Dle mych zkusenosti maji bezne ARMy vyrazne nizsi vypocetni vykon/MHz i pri srovani s Atomem, a ten ma zase vyrazne nizsi vykon/MHz nez mainstreamove x86 procesory. Jina vec je ale vypocetni vykon/Watt prikonu.
Postupně v ARM narůstá spousta věcí, které jsou tam pouze z historických důvodů (protože pro to byl před lety dobrý důvod, dnes už nikoli).Samozřejmě se ani jako zastánce ARMu redukční dietě nebráním.
Nicméně v absolutním výkonu ARM nemůže x86 konkurovat.Ovšem ale takovej Atom na 800MHz má víc než čtyřnásobnou spotřebu než OMAP3 na 800MHz. Takže na stejný zdroj jako Atom se může zapojit čtyřnásobek OMAPů
V neposlední řadě do vývoje a zdokonalování x86 byly vraženy takové prachy, jaké ARM mít nikdy nebude.No právě vendor lockin.
Myslím, že je čas, abych v této debatě skončil.Myslím, že je čas si vzpomenout, jak jsi říkal něco o tom, že už tu nebudeš přispívat. Ale jasně, jestli jsi to vyčetl z hvězd, tak je pochopitelné, že ani tahle předpověď ti nevyšla...
Ovšem SSE2 má dnes i hodně zastaralej křáp.To můžu rovnou napsat pro SSE3...
Jinak možná Vám to uniklo, ale autor příspěvku používal 64bitový asm.Což ovšem k řešení vůbec nebylo potřeba. Řešený problém lze naprogramovat klidně v BASHi, kde se bude wgetem volat server, který má už dávno rainbow tabulku předgenerovanou.
Vy jste tu přispěl spoustou nesmyslných tvrzení, o kterých nemáte moc ponětí.Muhehe vyhrál jsem
Další Vaše taktika je jen se politicky prosadit a někoho dostat.Přirozeně. Pokud se o ARM bude zajímat víc lidí, tak bude mít aspoň x86 konkurenci a třeba na to zapracuje. Navíc to může mít taky důsledek, že lidi budou lépe řešit úlohy zmíněné v zápisku.
memcpy
běží na CPU jako proces uživatele (se všemi omezeními a "iluzemi" o souvislé dostupné paměti, nepřerušovaném běhu atd atd), na rozdíl od DMA, které běží hardwarově jinde a "sahí si přímo na železo", takže ho ty "iluze" ani neomezují (a tudíž by měl OS problémy testovat oprávněnost přístupu do paměti) ani mu nepomáhají (takže neví, kde a zda má který proces namapované stránky).
Tak by se před inicializací provedl test dané stránky zda existuje na určeném místě a případně jí natáhl ze swapu (btw už to samotný natažení ze swapu pravděpodobně koná DMA).
A taky zda jde o jednu stránku, nebo třeba několik, zda a jaké práva k přístupu má uživatel ke kterým z nich a po natažení ze swapu by se dotaz rozdělil na několik, podle toho, kam by se to natáhlo a pak by se to po dokončení dotazu zase muselo označit jako modifikované - ono toho není málo, co je pro takovou věc potřeba zařídit, aby "iluze" víceuživatelského OS fungovala bezchybně.
Výhoda memcpy
je, že má všechny tyhle věci ošetřené přez cetrální mechanizmus (čili jednotně se zbytkem systému), který ani nevidí (takže to nemůže poškodit)
Tak by se před inicializací provedl test dané stránky zda existuje na určeném místě a případně jí natáhl ze swapuCož musí udělat jádro, čímž se zase dostáváme k syscallům a k tomu, že to rychlejší nebude.
Jj, ale to dneska znamená plýtvat ALU jednoho jádra na kopírování, při DMA by byl celý ALU k dispoziciTo jo, ale pro nějakou jinou úlohu; většina programátorů ale chce spíš, aby jejich program běžel rychle. Navíc započítej přepnutí kontextu, spuštění jiného programu, který nemá data v cache, návrat k původnímu programu, který už také nemá data v cache (použití toho enginu manipuluje přímo s pamětí; to, co bylo v cache CPU, už není pravda), celkově to dost snadno bude pomalejší, než prostě ta data přesunout.
a = cekej_na_nejaka_data_a_vrat_na_ne_ukazatel(); b = dej_mi_ukazatel_na_cilovy_blok(); c = rekni_mi_kolik_bytu_mam_kopirovat(); memcpy(b, a, c); // implementováno neblokující instrukcí, která používá DMA udelej_neco_s_daty_v_bloku(b); ...Zpracování té instrukce implementující memcpy bude chvíli trvat, jenže my v následujícím příkazu už potřebujeme, aby byla hotová. To znamená, že i když instrukce sama neblokuje, bude potřeba použít jinou, která zablokuje běh programu do doby, než se kopírování dokončí. Z kódu je přitom vidět, že memcpy dřív zavolat nemůžeme, protože nemáme všechna potřebná data. A takhle bude s velkou pravděpodobností vypadat hodně případů použití memcpy(), tím pádem se moc času neušetří a tranzistory investované do dané instrukce by bylo pravděpodobně lepší využít na něco jiného.
mezitím by byl CPU prakticky volnej pro jiný vlákno.Psal jsem jinde. Podle mě by to nefungovalo dobře kvůli přepínání kontextů - přepnutí kontextu nějakou dobu trvá a není to málo. U vlákna to možná není takový problém jako u procesu, ale i tak. Nové vlákno by ti vytěsnilo z cache data původního vlákna, přičemž by samo čekalo na data z paměti (jestliže kopírujeme tak velký objem dat, že se nám vyplatí přepnutí na jiné vlákno/proces, je to druhé vlákno/proces pravděpodobně cache-cold). Po přepnutí zpátky by na načtení dat muselo čekat původní vlákno. Do toho si předej, že to jiné vlákno předtím možná běželo na jiném CPU a musí se tedy počkat, až původní CPU vypíše data za svých cachí do paměti, aby je bylo možné načíst na nové CPU Tohle všechno by IMO v součtu zabralo mnohem víc času, než prostě udělat staré dobré kopírování kousek po kousku.
Ale při sdílené sběrnici se tomu nevyhneme, koneckonců DMA funguje taky na sdílené sběrniciNo nevim, podle mě je rozdíl mezi situací, kdy DMA vyvolá zařízení (mám smůlu, zrovna to padlo na mě a ne na Frantu) a kdy ho vyvolá Frantův proces (Franta mi užírá můj čas CPU)
Jakákoliv DMA má být z definice transparetní tedy neužírá žádný čas CPUTo je pravda. Jenže k čemu je mi dobrý čas CPU, když nemám instrukce/data, protože se musí dodat z paměti.
MOV AX,[0x4242] DIV BLA přece se to dá ve větším kontextu optimalizovat pro co nejmíň "bublin". I kdyby se proces po spuštění DMA zastavil, tak s DMA jako instrukcí bude task manager konat efektivněji, protože mu ubyde proces, na kterým má přepínat (a tedy i přepínací overhead).
ak by mohl být kód za DMA instrukcí zastaven a spuštěn až po dokončení DMA, mezitím by byl CPU prakticky volnej pro jiný vláknoTohle vicemene resi hyperthreading. Pokud bude nejaky program kopirovat spoustu pameti, tak bude vecne blokovany pristupem do pameti a nevyuzivane ALU jednotky mezi tim pouzije jine 'hypervlakno' bezici na stejnem jadre.
Řetězec musí bít zarovnané vpravoA sakra. Jdu se zarovnat vlevo, nerad bych dostal řetězcem
int lkp[10000]; void IntToStr8init() { int a0,a1,a2,a3; for (a3=0;a3<10;++a3) for (a2=0;a2<10;++a2) for (a1=0;a1<10;++a1) for (a0=0;a0<10;++a0) lkp[a3*1000+a2*100+a1*10+a0]=((a3+'0'))+((a2+'0')<<8)+((a1+'0')<<16)+((a0+'0')<<24); } void IntToStr8j(int num, char* str) { int p,q; p=num/10000; q=num%10000; *(int*)str=lkp[p]; *(1+(int*)str)=lkp[q]; }