Zobrazit předchozí téma :: Zobrazit následující téma |
Autor |
Zpráva |
perry

Založen: 28. 07. 2009 Příspěvky: 879
|
Zaslal: 9. únor 2011, 22:22:26 Předmět: |
|
|
citace: |
No ale prasacina to bude v kazdom pripade Smile |
Myslel jsem si to ... Díky... přepis na pole [4][4] volá  _________________ Perry.cz |
|
Návrat nahoru |
|
 |
VladR
Založen: 30. 07. 2007 Příspěvky: 1322 Bydliště: Greater New York City Area
|
Zaslal: 9. únor 2011, 22:40:53 Předmět: |
|
|
Ono to dost zavisi od architektury. Napr. na starom Pentiu I, s inou architekturou Execution Units a Cache contention, by to vyzeralo inak a tie lokalne premenne by kludne mohli byt rychlejsie (ale teraz sa mi nechce spatne dohladavat pravidla ich fungovania v manuale).
Samozrejme, najrychlejsi kod si vzdy napises sam, v cistom assembleri, kde mas priamu kontrolu nad tym, co je v registri a co nie.
Kebyze si sa velmi nudil, tak by som to celkom doporucil - stravit s tym jeden den a pozriet co to da oproti beznemu MS compileru.
Plus, spravit SSE verziu. A tam to mas uplne ze najrychlejsie - vsetko v registroch a v jednej instrukcii nahradis mnohopocetne nasobenie/scitanie  |
|
Návrat nahoru |
|
 |
nou

Založen: 28. 07. 2007 Příspěvky: 1051
|
Zaslal: 9. únor 2011, 22:44:57 Předmět: |
|
|
ked sa budes STRAAAAAASNE nudit tak mozes pouzit toto http://www.agner.org/optimize/
inak preliminary optimization is root of all evil. takze na optimalizacie sa teraz vyser. ked zistis ze to je pomale tak to ries potom. sice povedal by som ze taka zmena O(X^n) na O(n^2) by bola velmi vhodna hned ako to clovek pise. _________________ Najjednoduchšie chyby sa najtažšie hľadajú. |
|
Návrat nahoru |
|
 |
VladR
Založen: 30. 07. 2007 Příspěvky: 1322 Bydliště: Greater New York City Area
|
|
Návrat nahoru |
|
 |
rezna
Založen: 27. 07. 2007 Příspěvky: 2156
|
Zaslal: 9. únor 2011, 23:39:32 Předmět: |
|
|
ja bych rekl ze to extremne hrotite - pokud presel od C# k C++ tak na nejake SSE je znacne brzo ... |
|
Návrat nahoru |
|
 |
VladR
Založen: 30. 07. 2007 Příspěvky: 1322 Bydliště: Greater New York City Area
|
Zaslal: 10. únor 2011, 00:03:35 Předmět: |
|
|
To hej, ale myslim ze staci, ked bude mat aspon povedomie o tom, ze take veci existuju a ze aj ten C++ kod je stale de facto prilis hi-level a ze to vonkoncom nie je sranda ani v C++ napisat rychly kod.
Neskor aspon bude vediet co a kde ma hladat.
A to vecerne citanie od intelu nikdy nie je na skodu. Clovek znacne precitne, ked si precita ako vlastne funguje architektura sucasnych procesorov.
Naposledy som nieco take robil s 8088 CPU a odvtedy sa zaber CPU znacne rozsiril a aj mna mnohe veci v tom Intelovskom manuale prekvapili, ze ako to vlastne teraz funguje.
Clovek sa potom na kod pozera uplne inak...
Mne bezny C++ kod teraz pripada ako Karel, alebo LOGO... |
|
Návrat nahoru |
|
 |
Vilem Otte

Založen: 18. 09. 2007 Příspěvky: 462 Bydliště: Znojmo - Sedlesovice, Kravi Hora
|
Zaslal: 10. únor 2011, 00:28:51 Předmět: |
|
|
Proč vektoizovat kód?
V drtivé většině případů NENÍ potřeba kód vůbec vektorizovat, vektorizace přinese spousty problémů a skalární operace se zpomalí (XMM registry nejsou vhodné pro práci s jediným číslem, na to je tad FPU), a horizontální operace (skalární součiny například) se zpomalí hodně (zkuste si napsat jednoduchý FPU dot product a SSE2 dot product a SSE4 dot product přes dpps instrukci - zjistíte, že pokud dokážete napsat dobrý FPU kód, tak SSE2 bude pomalejší a SSE4 jen velmi nepatrně rychlejší, ale následné uložení do float čísla z 128-wide registru to zpomalí a na většině CPU může FPU časově i zvítězit).
V 90 procentech zbylých případů je za vás dostatečně schopný provést vektorizaci do SSE kompilér (často ji nenapíšete o moc lépe - obvykle spíše hůře) ... samozřejmě mám na mysli reálný kompilér, ne MSVC - nové GCC je narozdíl od předchůdců na vektorizaci vynikající, ICC je nejlepší (a jeho černá magie ).
Navíc používání inline ASM v MSVC je overkill (napsání __asm je velmi drahá záležitost co se výkonu týče).
Ve zbylé části se jedná především o funkce, kde vektorizujeme cyklus (2x2 sse-packet traversal při ray tracingu - ovšem tady je další problém, nebudu rozvádět; násobení matice x pole bodů; apod.). Tady to smysl MÁ, ale musíte mít dobré structy (SoA raději než AoS), dobře napsané a postavené pointery (a už tady máme problém 32-bit vs. 64-bit aplikace), a tedy včas a dobře prefetchovat data v cachích (protože pokud to nemáte, dojde ke cache miss - což vektorizovaný cyklus výkonově zabije).
Takže abych to shrnul, dokud nevíte něco hlubšího o kompilérech a o procesorech - nemá se smysl o SSE bavit, natož v něm něco psát. Většinou jej stejně potřebovat nebudete, a když jo, tak to většinou skončí u compiler flagu -mssex ... za x doplňte odpovídající číslo.
Pozn. Pokud nevite co je SoA, AoS, FPU, SIMD, cachovací linka, cache miss, a další pojmy - nemá smysl s SSE začínat, máte na to ještě čas.
Proč SSE?!
Je standard, ale nové AVX vypadá slibněji (8-wide SIMD ... nicméně Core quad-core i7 s SSE výkonově převálcuje Sandy Bridge i5 s AVX ... a za podobnou cenu se dají sehnat jak Sandy Bridge i5, tak quad-core i7. Uvidím jak dopadne Bulldozer), i když mě nepřijde zrovna nejlepší, mnohem lepší mi přijde 16-wide SIMD (plánován u zrušeného Larabee - nevím jak to je u Knights Ferry?), protože do něj nacpete celou matici.
Nicméně, pokud potřebujete něco velmi paralelizovat a urychlovat - docela byste si měli vystačit třeba se 4 jádry a kompilérově vektorizovaným kódem. Pokud potřebujete počítat ještě rychleji, tak buď uvažujte o slušné GPU a OpenCL (nebo GPGPU), nebo 12-core Operton (pokud máte dostatek financí), případně 2x12-core na deskách pro něj.
EDIT:
citace: |
by to vyzeralo inak a tie lokalne premenne by kludne mohli byt rychlejsie (ale teraz sa mi nechce spatne dohladavat pravidla ich fungovania v manuale). |
Local proměnné jsou rychlejší i na moderních procesorech, ne pouze na staré P1, na Core i3 ti dají hodně ... ušetříś si cache missy a vše máš v cache, navíc "chytré" kompiléry je někdy nahradí i registrem (a ani je nedeklarují).
citace: |
- inline se už tuším nemusí používat, moderní kompilery ho ignorují a inlinují dle libosti |
To není tak docela pravda, moderní kompiléry neinlinují dle libosti, spíše dneska je overhead za volání téměř nulový (procentuálně k výkonu), takže to obvykle nepocítíš ... jinak inline je skutečně inline (případně pro kompiléry co inlinují dle libosti funguje __forceinline). Ale pozor inline neznamená vždy vyšší rychlost.
Ad Matrix4x4.h soubor, je napsaný docela prasácky co se výkonu týče... templates a overloading může být pro výkon docela veliké zlo (v tomto případě by jej to při intenzivním nasazení asi zabilo).
Static_casty taky nejsou nic dobrého co s výkonu týče (a math.h sin a cos také ne - a rozhodně také nic přesného v případě fpmath = fast, jde to lépe)
Pokud se má jednat pouze o transformační matici, tak funkce isIdentity jde udělat lépe (if((a noteq x) or (b noteq x) or ... or (z noteq x)) je docela náročné v tak velkém počtu orů).
Identity by mělo jít rychleji přes memcpy (a někde si ji staticky předpočítat a uložit).
Před operator je zbytečné psát inline, protože v C++ jsou operatory ve většině kompilerů defaultně inline (hlavně do nich nepsat nic velkého!)
A celkově kód se bude chovat jako pomalý (jde to mnohem lépe). Nicméně jako základ před řádnou optimalizací, pokud se zbavíš templatů, by se to dalo použít (raději použij define makro) _________________ Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration. |
|
Návrat nahoru |
|
 |
frca

Založen: 28. 07. 2007 Příspěvky: 1561
|
Zaslal: 10. únor 2011, 01:23:16 Předmět: |
|
|
Vilem Otte napsal: |
Local proměnné jsou rychlejší i na moderních procesorech, ne pouze na staré P1, na Core i3 ti dají hodně ... ušetříś si cache missy a vše máš v cache, navíc "chytré" kompiléry je někdy nahradí i registrem (a ani je nedeklarují). |
A fakt jsou rychlejší i než "local" pole? U dynamicky alokovaných polí je to jasné, ale tady mi to pořád nějak hlava nebere. _________________ www.FRANTICWARE.com |
|
Návrat nahoru |
|
 |
Marek

Založen: 28. 07. 2007 Příspěvky: 1782 Bydliště: Velká Morava
|
Zaslal: 10. únor 2011, 03:58:36 Předmět: |
|
|
Co je špatného na #pragma once? Umí to VC++ i GCC (defaultně) a teoreticky to může trochu urychlit kompilaci.
Podle mě tady řešíte moc pokročilé věci a hlavně už je to off-topic. Autor vlákna tvrdí, že je začátečník. Takže mu radím, aby tady tu pokročilejší diskuzi radši ignoroval, prozatím.
Vilem Otte> Podle mě všechny compilery nahrazují lokální proměnné registrem, pokud to jde. Říká se tomu alokace registrů a dělá se to všude, protože to má brutální vliv na výkon. Vypnutá alokace registrů v compileru může způsobit, že se vygeneruje i 5x pomalejší kód. Funguje to tak, že se všem lokálním proměnným přiřadí registry (čísla) a provede se přejmenování všech registrů tak, aby jich bylo co nejmíň, ale aby kód dělal furt to samé. Pokud těch registrů bude mít víc, než se vejde do procesoru, hodí některé z nich do paměti. Kód, co používá 50 proměnných, si klidně může vystačit i s 6 registry a žádnou pamětí. Závisí to na tom, co ten kód dělá.
S alokací registrů je ale několik problémů:
1) Je to NP-complete, v praxi compiler nikdy neudělá perfektní kód.
2) Pokud procesor neumí indexovat registry, musí compiler všechny pole indexované nekonstantou hodit do paměti (to je odpověď na otázku, proč pole mohou být pomalejší, když se např. nerozvine cyklus, který nad ním iteruje).
3) Přejmenování registrů může způsobit, že některé optimalizace nebude možno provést (např. může úplně znemožnit automatickou vektorizaci). Naopak některé optimalizace mohou kód transformovat tak, že alokace registrů dopadne o dost hůř (vyrobí víc registrů). Tzn. špatně zvolené pořadí optimalizací v compileru může kód i zpomalit. Je to docela magie někdy.  _________________ AMD Open Source Graphics Driver Developer |
|
Návrat nahoru |
|
 |
Tringi

Založen: 28. 07. 2007 Příspěvky: 290
|
Zaslal: 10. únor 2011, 09:13:48 Předmět: |
|
|
Vilem Otte napsal: |
Ad Matrix4x4.h soubor, je napsaný docela prasácky co se výkonu týče... templates a overloading může být pro výkon docela veliké zlo (v tomto případě by jej to při intenzivním nasazení asi zabilo). |
To je pěkná blbost. Templejtky mohou zpomalit pouze samotnou kompilaci (i velmi hodně, o tom žádná) a pokud neuděláš žádnou botu, výsledný kód bude identický jako kdybys nahradil typový argument přímo žádaným typem. Overloading podobně. Která z konkrétních funkcí se volá je vyřešeno za kompilace.
Vilem Otte napsal: |
Static_casty taky nejsou nic dobrého co s výkonu týče |
static_cast implikuje konverzi, úpravu adresy pointeru a často vzniku žádné instrukce navíc nezavdá.
Vilem Otte napsal: |
Nicméně jako základ před řádnou optimalizací, pokud se zbavíš templatů, by se to dalo použít (raději použij define makro) |
O vektorizaci víš hodně ale C++ není tak úplně tvá doména, co?
Eosie napsal: |
Co je špatného na #pragma once? Umí to VC++ i GCC (defaultně) a teoreticky to může trochu urychlit kompilaci. |
Představ si symlinky, hardlinky, junction pointy a další kolize názvů souborů. Jistě, pokud je u tvého kompilátoru dobře zdokumentovaná, pak proč ne, koneckonců pro urychlení kompilace byla vymyšlena, ale musíš si být jistý, že ji jiný (hloupější) kompilátor bude brát stejně, nebo vůbec že ji nebude prostě ignorovat. Navíc, v seriózním průmyslu máš mnohdy na kód požadavek držet se standardu, a pak je vyřešeno. _________________ WWW | GitHub | TW |
|
Návrat nahoru |
|
 |
perry

Založen: 28. 07. 2009 Příspěvky: 879
|
Zaslal: 10. únor 2011, 09:23:26 Předmět: |
|
|
Co jsem o templates četl, tak jsem je pochopil jako "typově kontrolované #define", navíc od C# se tvoří při překladu, takže v runtimu by nemělo použití template nic brzdit (na rozdíl od genericity v .NET).
citace: |
Pokud se má jednat pouze o transformační matici, tak funkce isIdentity jde udělat lépe
|
Tady moc nevím, co myslíš tím "lépe" _________________ Perry.cz |
|
Návrat nahoru |
|
 |
nou

Založen: 28. 07. 2007 Příspěvky: 1051
|
Zaslal: 10. únor 2011, 10:05:30 Předmět: |
|
|
no hlavne lokalne premenne su na stacku. a ako vieme tak stack je jedna oblast pamete ktora sa neustale znovu pouziva. takze je velmi pravdepodobne ze bude v L1/2 cache. co sa o heap neda povedat.
inak gcc ma optimalizaciu ze ak je na zaciatku klasicky guard #ifndef BLA #define BLA tak preskakuje cely subor. http://gcc.gnu.org/onlinedocs/cppinternals/Guard-Macros.html _________________ Najjednoduchšie chyby sa najtažšie hľadajú. |
|
Návrat nahoru |
|
 |
perry

Založen: 28. 07. 2009 Příspěvky: 879
|
Zaslal: 10. únor 2011, 11:24:50 Předmět: |
|
|
Přepsáno na pole a OK... akorát co jsem zkoušel, tak operace s polem přes for jsou pomalejší (vnitřní cyklus mění druhý index) , než přímo vypsat natvrdo kód [0][0], [0][1] atd
----
citace: |
kde máš operator[]?
|
Tak když jsem to přehodil do pole, tak proč psát operátor [], když můžu napsat
(Leda že to není tak hezké )
----
A ještě jeden spíš offtopic dotaz k tomu... mám to udělat jako *.dll (případně jaký typ) nebo to vždycky přidávat jako zdrojáky k projektu ? _________________ Perry.cz |
|
Návrat nahoru |
|
 |
Vilem Otte

Založen: 18. 09. 2007 Příspěvky: 462 Bydliště: Znojmo - Sedlesovice, Kravi Hora
|
Zaslal: 10. únor 2011, 12:38:55 Předmět: |
|
|
citace: |
To je pěkná blbost. |
Není, přečti si něco o overloadingu a jeho vlivu na výkon ... zjistíš, že jsou situace kdy vliv má.
citace: |
static_cast implikuje konverzi, úpravu adresy pointeru a často vzniku žádné instrukce navíc nezavdá. |
Samozřejmě, myslel jsem v tomto případě:
kód: |
T cosinus = static_cast<T>(cos(static_cast<double>(angle))); |
je hrozná věc, co se výkonu týče, co můžeš napsat, lepší je napsat si funkci fast_cosf, s jednou Newton-rhapson iterací (bude mít vyšší přesnost a je rychlejší, a nemusíš dělat typecasty. Nebo i "blbý" cosf/sinf bez typecastů.
nicméně ta druhá část - že upravíš adresu bez vzniku instrukce, jak jsi napsal je s prominutím úplná pič*vina - pokud upravuješ adresu pointeru, VYGENERUJEŠ instrukci (někdy instrukce), jestli ty ne - tak tvůj kompilér bych chtěl mít.
Na tvůj poslední komentář bych mohl začít flame o tom, jestli umím C++, a prozatím si nikdo nestěžoval na výkon mých programů, ani kvalitu (a věř, že jich je hodně) - až se někdo takový objeví, tak to uvážím - do té doby takové poznámky raději nepiš  _________________ Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration. |
|
Návrat nahoru |
|
 |
nou

Založen: 28. 07. 2007 Příspěvky: 1051
|
Zaslal: 10. únor 2011, 13:20:27 Předmět: |
|
|
perry napsal: |
A ještě jeden spíš offtopic dotaz k tomu... mám to udělat jako *.dll (případně jaký typ) nebo to vždycky přidávat jako zdrojáky k projektu ? |
kedze je to template a musi sa includovat hlavickovy subor tak ako zdrojaky. ak su to rozne male utility a tak tak by som to dal do statickej lib popripade dll. problem dll je pomalsi start kedze linker musi nalinkovat pri starte vsetky dll. _________________ Najjednoduchšie chyby sa najtažšie hľadajú. |
|
Návrat nahoru |
|
 |
|