.[ ČeskéHry.cz ].
Matrix class - spravnost kodu
Jdi na stránku Předchozí  1, 2, 3, 4  Další
 
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> C / C++
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
frca



Založen: 28. 07. 2007
Příspěvky: 1561

PříspěvekZaslal: 10. únor 2011, 13:45:19    Předmět: Odpovědět s citátem

Já osobně nikdy nic necpu do dll, pokud to není nutné (licence knihovny atd.). Je to ale spíš takový nějaký můj pocit daný tím, že nevím, co pozitivního by mi taková dll knihovna přinesla.
_________________
www.FRANTICWARE.com
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
nou



Založen: 28. 07. 2007
Příspěvky: 1051

PříspěvekZaslal: 10. únor 2011, 14:24:52    Předmět: Odpovědět s citátem

usetrenie miesta v pameti. ak kniznicu pouziva viacero processow tak staci aby bola v pameti iba raz.
bezpecnost. ak je v kniznici chyba staci aktualizovat iba ju a nie cely program.

samozrejme ak je to interna kniznica ktora je pouzivane prakticky len danym programom tak nema zmysel davat to naschaval do dll. ak to ale ma byt extrena kniznica vtedy dava pouzitie dll zmysel.
_________________
Najjednoduchšie chyby sa najtažšie hľadajú.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
frca



Založen: 28. 07. 2007
Příspěvky: 1561

PříspěvekZaslal: 10. únor 2011, 14:31:18    Předmět: Odpovědět s citátem

Pokud je ten dll soubor nahraný přímo v adresáři u programu, tak systém nepozná, že už třeba někde jinde stejná knihovna nahraná je, ne? (Tzn. z indentického souboru, ale z jiné cesty.) Mluvím například o knihovně SDL, která je typicky přibalená ke hře. Tam je to dll jen proto, že musí z důvodu licence. A kopírovat svoji dll knihovnu do systémového adresáře mi taky nepřipadá nejšťastnější z toho důvodu, že widle nemají žádnou správu závislostí, takže vznikne akorát tak silné dll hell.
_________________
www.FRANTICWARE.com
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
if.then



Založen: 13. 04. 2008
Příspěvky: 579

PříspěvekZaslal: 10. únor 2011, 14:40:02    Předmět: Odpovědět s citátem

1. Templates - nechápu, vždyť v renderování grafiky má opodstatnění POUZE float a double (ať už kvůli operacím např. v OpenGL, kvůli binárním souborům nebo kvůli něčemu úplně jinému), podle toho, jak velké chceš objekty se mezi nimi rozhodneš.

2. Je tam moc funkcí. Měl bys začít s pár důležitými funkcemi (součin matic, identity, násobení trojrozměrného vektoru...) a pak - pokud to uznáš za vhodné - přidat další.

3. Public data jsou, ehm... zdržím se výrazů jako prasárna apod., ale prostě je to trošku složitější. Zaprvé je mnohem hezčí, když ta matice vypadá jako pole 16 prvků s "přidanou hodnotou", zadruhé si představ, že budeš chtít checkovat chyby. Třeba u matic bys v debugu chtěl kouknout, zda jim nepřiřazuješ INFINITY nebo NAN (not a number). Pokud v té chvíli budeš mít nadefinovaný operátor [] a budeš přiřazovat pouze přes něj, tak se nebudeš muset uchylovat k šíleným hackům (třeba pole 16 prvků pro debug a třídu s operátorem [] pro release), abys toto chování vzal.

4. Nadefinovat namespace Math je kapánek o hubu, je to tak rozšířené slovo, že bych se nedivil, kdyby ho používaly např. i nějaké knihovny. Pak tam předefinuješ funkci a bum - linker error je na světě. Osobně preferuji prefixovat personální projekty přezdívkou (třeba namespace ifthen).

5. Diskutuje se o tom, co by mělo být struct a co class - v C++ je struct vlastně skoro to samé jako class (snad kromě implicitních přístupových práv), takže je to na každém - já beru structy jako třídy s pár public proměnnými, pár funkcemi a bez konstruktoru a destruktoru, ke kterým se přistupuje jen v nějaké nadřazené třídě a tam jsou private - takže třeba třída pro UV. Pokud to jednu z těchto podmínek nesplňuje, tak píšu class. Ale tohle je docela na tobě, C++ je dost volné a umožňuje ti to psát, jak sám uznáš za vhodné. Ale obyčejně se velké třídy s konstruktorem/destruktorem píšou jenom jako class.
_________________
For guns and glory, go to www.ceske-hry.cz.
For work and worry, execute VC++.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
perry



Založen: 28. 07. 2009
Příspěvky: 879

PříspěvekZaslal: 10. únor 2011, 15:06:10    Předmět: Odpovědět s citátem

Dll jsem myslel z důvodu případného update ... změním jenom knihovnu a ne celý *.exe... ale to už je detail

citace:

2. Je tam moc funkcí. Měl bys začít s pár důležitými funkcemi (součin matic, identity, násobení trojrozměrného vektoru...) a pak - pokud to uznáš za vhodné - přidat další.

Přepisuju si knihovnu, kterou používám v C#... všechny ty metody víceméně někde využívám, tudíž tam není nic "navíc" ... možná některé operátory

Add 3.: Vyházel jsem proměnné M11, M12 atd a místo nich mám teď M[4][4].. pak už nevidím význam operatoru []
_________________
Perry.cz
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Tringi



Založen: 28. 07. 2007
Příspěvky: 290

PříspěvekZaslal: 10. únor 2011, 15:35:13    Předmět: Odpovědět s citátem

Vilem Otte napsal:
citace:
To je pěkná blbost.

Není, přečti si něco o overloadingu a jeho vlivu na výkon Wink ... zjistíš, že jsou situace kdy vliv má.

Tak to asi myslíme pod pojmem overloading něco úplně jiného. Na zběžně položených pár dotazů googlu jsem se dostal akorát na všelijaké diskuze, které v zásadě došly k negativnímu závěru. Máš-li na mysli nějaký konkrétní paper, pošli odkaz, protože si nedokážu ani představit, jak by (dle dnes nejběžnějších ABI) mohlo přetěžování jakkoliv ovlivnit výkon.

Vilem Otte napsal:
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ů.

Ale o tom, že standardní implementace těchto funkcí jsou pomalé se vůbec nemusíme bavit. To, že takto napsaný static_cast implikuje konverzi mezi float (je-li T float) a double, ale není vina static_castu. Proto je psát "static_cast není nic dobrého" blbost! Použiju-li static_cast pro, například, konverzi mezi typy ukazatelů, nevygeneruje se na mainstreamových platformách žádná instrukce. Jak to může ovlivnit výkon prosímtě?

Vilem Otte napsal:
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.

V té větě mám "a" ...možná jsem ji mohl lépe přeformulovat, ale to je asi jedno.

Vilem Otte napsal:
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š Wink

Až mi vysvětlíš ten overloading a proč pomalost konverze svádíš na static_cast, budu si možná myslet něco lepšího Wink
_________________
WWW | GitHub | TW
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
nou



Založen: 28. 07. 2007
Příspěvky: 1051

PříspěvekZaslal: 10. únor 2011, 16:31:51    Předmět: Odpovědět s citátem

Tringi napsal:
Tak to asi myslíme pod pojmem overloading něco úplně jiného. Na zběžně položených pár dotazů googlu jsem se dostal akorát na všelijaké diskuze, které v zásadě došly k negativnímu závěru. Máš-li na mysli nějaký konkrétní paper, pošli odkaz, protože si nedokážu ani představit, jak by (dle dnes nejběžnějších ABI) mohlo přetěžování jakkoliv ovlivnit výkon.

no overloading ma vplyv na vykon. ako vieme tak virtualne fukcie su implementovane cez vtable. teda ak zavolas objekt->normalna_metoda() tak prekladac vrazy do kodu priamo adresu metody. ak je objekt->virtualna_metoda() tak sa najpr musi pozriet do tej vtable a pouzit adresu z tejto vtable. preto je tam nejaky overhead.
_________________
Najjednoduchšie chyby sa najtažšie hľadajú.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Tringi



Založen: 28. 07. 2007
Příspěvky: 290

PříspěvekZaslal: 10. únor 2011, 16:37:09    Předmět: Odpovědět s citátem

Já tak trochu tuším, že tady někteří zaměňují overloading (přetěžování funkcí a operátorů) za overriding (převažování/překrývání virtuálních funkcí u polymorfizmu). Cool

EDIT: Jinak nou máš samozřejmě pravdu, dynamický dispatch přes vtable je volání přes dva pointery, a to o něco pomalejší samozřejmě je. Nicméně na moderních architekturách to může být stále rychlejší než blbě napsaný IF.
_________________
WWW | GitHub | TW
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Vilem Otte



Založen: 18. 09. 2007
Příspěvky: 462
Bydliště: Znojmo - Sedlesovice, Kravi Hora

PříspěvekZaslal: 10. únor 2011, 19:33:01    Předmět: Odpovědět s citátem

MSVC říká, že overloading se nevyplácí... btw verze kompiléru:
kód:
; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01

Není nejnovější, ale co už...

Program předgeneroval náhodné float čísla (jak do vec3/OverloadedVec3 struktur s float a, b, c v nich, tak jednoduše do array of float). OverloadedVec3 měl 2 operátory + (jeden pro float, a druhý pro druhý OverloadedVec3, vec3 měl vše jako metody). Oba dva operátory byly testovány 100 000 000krát, prokládaně (že se v každé iteraci cyklu provedli oba, ne ve 2 cyklech).

MSVC vyprodukovalo zajímavé assembly pro FPU:
Overloaded - http://pastebin.com/YTxA7Grx (369 lines)
Procedural - http://pastebin.com/9jw0SsE4 (187 lines)

Mno, overloading tady má performance hit - další věc je, kolikrát děláte se 100 000 000 prvky na CPU?
Co je zajímavé na tom kódu - tak ač byly všechny optimalizace a podstatné věci zapnuté (-Ox, -Ot, -GL, ... a fp:fast), je v overloaded kódu podezdřele hodně zbytečných movů - celkem 12! Což je zřejmě "kvalita" MSVC kompiléru, zkusím to ještě na GCC 4.2 a ICC 12.0. Nicméně lze vidět že overloaded kód má nějaké instrukce navíc, ale není to tak horké (dokud skutečně neděláte se 100 000 000 prvky) - a obvykle je bottleneck rozhodně jinde.

Ad static_cast - taky jsem, pravda, špatně formuloval - jak jsem psal v předchozím postu, tam se nehodí (neměl jsem na mysli že static_cast obecně je špatný)... např. sinus nejlépe (co se rychlosti týče, na 12.9 procent přesně - tolik je maximání odchylka, a počítám již s úhlem mezi -pi do pi) uděláš takto:
kód:

#ifdef _SINGLE_PRECISION
#define FOUR_DIV_PI 1.27323955f;
#define FOUR_DIV_PI_SQR 0.40528473f;
#elif defined _DOUBLE_PRECISION
#define FOUR_DIV_PI 1.2732395447351627;
#define FOUR_DIV_PI_SQR 0.4052847345693511;
#endif

#ifdef _SINGLE_PRECISION
float sinf(const float &angle)
{
#ifdef _BETTER_PRECISION
   float y = FOUR_DIV_PI * angle + FOUR_DIV_PI_SQR * angle * fast_abs(angle);
   return 0x3e666666 * (y * fast_abs(y) - y) + y;
#else
   return FOUR_DIV_PI * angle + FOUR_DIV_PI_SQR * angle * fast_abs(angle);
#endif
}
#elif _DOUBLE_PRECISION
double sind(const double &angle)
{
#ifdef _BETTER_PRECISION
   float y = FOUR_DIV_PI * angle + FOUR_DIV_PI_SQR * angle * fast_abs(angle);
   return 0x3fcc7ae147ae147b * (y * fast_abs(y) - y) + y;
#else
   return FOUR_DIV_PI * angle + FOUR_DIV_PI_SQR * angle * fast_abs(angle);
#endif
}
#endif


Edit: s #define _BETTER_PRECISION je asi 0.2 procent maximalni odchylka přesnosti - takže docela rychlostí i přesností likviduje klasický sin. Cosinus je už jednoduchý, jen se musí úhel přepočítat do +pí až -pí (to jde rychle a jednoduše).

To Igor - ať tu nepostuju furt - ano overloading BY MĚL vyprodukovat stejně rychlý kód, fakt je, že kompilátory asi nejsou úplně ideální a nějaký "garbage" navíc to bohužel vyprodukuje - a tedy kód NENÍ stejně rychlý (pak záleží jak je kompilátor dobrý, některé se přiblíží více, některé méně). Nicméně overloading může také znepřehlednit kód pro cílového uživatele.
_________________
Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration.


Naposledy upravil Vilem Otte dne 10. únor 2011, 20:02:46, celkově upraveno 2 krát
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail Zobrazit autorovi WWW stránky
igor



Založen: 28. 07. 2007
Příspěvky: 196

PříspěvekZaslal: 10. únor 2011, 19:54:49    Předmět: Odpovědět s citátem

No a nebude to něčím jiným než overloadingem? Nevím, jestli jsem ten popis dobře pochopil a nějak nevím, jestli se tady všichni baví o tom samém, ale vec3/OverloadedVec3 se asi líší trochu víc než názvy funkcí/metod? Overloading by (pokud se nějak šeredně nepletu) přece měl fungovat tak, že kompilátor s názvy funkcí provede name mangling tak, aby se každá funkce líšila jménem (přilepí tam další znaky podle typů parametrů apod.) a mělo by být jedno, jestli se původně v kódu různé funkce jmenovaly stejně (s různými typy parametrů) nebo úplně jinak. Je to spíš něco blízko kategorii "syntaktický cukr" a umožňuje jenom použití pohodlnějších názvů v kódu.




EDIT:

No a není to teda spíš tím, že jedna verze má operátory a druhá metody? To by snad taky mělo být stejné, ale nedělal by s tím divné věci kompilátor spíš než jenom s názvy metod (třeba používá specifické optimalizace pro operátory, které mají většinou určitým způsobem podobnou sémantiku?). Dělá to samé, když v obou verzích jsou normální metody, přičemž v jedné se jmenují stejně a ve druhé různě?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Tringi



Založen: 28. 07. 2007
Příspěvky: 290

PříspěvekZaslal: 10. únor 2011, 20:39:06    Předmět: Odpovědět s citátem

Přesně tak, operátor je jen extra pojmenovaná funkce a syntaktický "cukr" Wink
U GCC se tento rozdíl smaže na GIMPLE úrovni, mnohem dřív než se dostane na generování instrukcí.

Koukám na ten první ASM výstup a nestačím se divit, že tohle leze z MSVC. Nejsem sice expert na x86 instrukce ale zdá se mi, že některé ty MOVy jsou zcela zbytečné, snad jako by to bylo bez některých optimalizací, a další vypadají jako by se ti tam dostal aliasovaný pointer nebo coloringu chyběl registr. Nemůžeš ukázat kód toho vec3/OverloadedVec3?

Btw. ta aproximace sin/cos je pěkná.
_________________
WWW | GitHub | TW
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Vilem Otte



Založen: 18. 09. 2007
Příspěvky: 462
Bydliště: Znojmo - Sedlesovice, Kravi Hora

PříspěvekZaslal: 10. únor 2011, 22:02:13    Předmět: Odpovědět s citátem

Operátor by měla být normální funkce s __forceinline, při kompilaci by se mělo překódovávat její jméno (a nakonec u ní by měl být nějaký index - aby se "odlišily různé overloady" - tedy overloading je jenom jinak pojmenovávání funkcí pro uživatele - kompilér je poté vezme jako standardní funkce (problém je, že u nich nemusí zadefinovat __forceinline - to už záleží na délce procedury operátoru a zda se do ní posílá struct - alespoň u MSVC to tak je, ale záleží na kompilátoru).

Samozřejmě Trinigi měl teoreticky pravdu - overloading by neměl mít žádné instrukce navíc, já se na to díval z praktického hlediska (především MSVC, ICC afaik generuje pro overloady mnohem kratší kód než MSVC), a tam mě praxe naučila - dokud není nutné pro přehlednost, nepoužívat overloady (zpomalují v něm). Tedy na kompiléru záleží.

Kód tady pošlu, jak budu doma (teď večer jsem odjel pryč, a nepíši ani z mého PC), i s ukázkovou aplikací (možná zkompilovanou pod GCC i ICC).

Možná by stálo za to, hodit nějaké ty chytré funkce, jako tento sin/cos na wiki - možná to tam napíšu (zkusím ještě nějaké pěkné věci vyhrabat). Dokonce ten sin/cos mám napsaný i v SSE Smile

Jinak skutečně, ty movy tam jsou navíc (a je jich dost) - optimálně by to mělo asi o 4 instrukce navíc (což, pokud neděláš opravdu extrémnosti, neznamená ve výkonu nic navíc - bohužel třeba u mého path traceru to jde poznat (přešel jsem z overloaded funkcí na neoverloaded - a nárust byl cca 0.4 - 1.6 procenta ve výkonu ... jenom bych ale dodal, že to bylo spíše způsobeno tím, že operátory nebyly kompilérem inlinovány a jednalo se o overhead při spoustě volání), pravda to JE extrémnost)
_________________
Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail Zobrazit autorovi WWW stránky
perry



Založen: 28. 07. 2009
Příspěvky: 879

PříspěvekZaslal: 11. únor 2011, 09:49:33    Předmět: Odpovědět s citátem

Ta funkce na fast sin/cos je sice pěkná, ovšem v porovnání s klasikou sin/cos

kód:

float angle, c, cc;
for (int i = 0; i < 100000000; i++){
   angle = rand() / 10000.0f;
   //c = sin(angle);
   cc = MyMathUtils::sinf(angle);
}


Je sinf rychlejší o cca. 0.01s (kód běží pro klasický sin 3.25s .. % si spočtěte Very Happy) ... což mi moc jako velká úspora nepřijde.. ale možná dělám něco blbě
Zkoušel jsem to sinf i bez volání funkce.. přímo inline ji napsat a rozdíl není moc velký .. navíc je to zkoušeno bez _BETTER_PRECISION

Edit: Zkoušel jsem vyhodit templates a nahradit je za #define.... rychlost je prakticky stejná, resp. neměřím žádné znatelné rozdíly... z toho my vychází použití templates jako lepší, vzhledem k typové kontrole a případnému použití matice jako <int> apod. (V třídě Vector stejně template používám, protože vector<int>, vector<byte> mám pro použité v pixel grafice, kdy si v něm ukládám pozice pixelů)
_________________
Perry.cz
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
rezna



Založen: 27. 07. 2007
Příspěvky: 2156

PříspěvekZaslal: 11. únor 2011, 10:59:52    Předmět: Odpovědět s citátem

@perry - to co tu pisou Vilem Otte, VladR, eosie, ... muzes klidne pro zatim vyhodit z hlavy a resit normalnejsi veci

az budes ve stavu ze budes potrebovat optimalizovat i uplne capiny, treba kvuli raytraceru, tak se sem vrat a pocti si

jinak tyhle veci aktualne vubec smysl nemaji a vzdy plati radeji hezci kod o malicko pomalejsi nez delat v aktualni fazi premature-optimization - to vede akorat do pekla
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Houp



Založen: 28. 07. 2007
Příspěvky: 672

PříspěvekZaslal: 11. únor 2011, 12:04:15    Předmět: Odpovědět s citátem

Co tu myslím nezaznělo, jestli je třeba mít T jako typ parametru u všech metod. Jestli by někde neměl být nějaký typ natvrdo.

Např. si nejsem jist, jestli u matice, která používá inty, je vhodné mít scale jen na inty (nikdy to scalem nezmenšíš) a takových příkladů by se asi našlo více.

Tedy ode mě malé upozornění, že to, že budeš mít hlavní datovou strukturu typu T, tak jestli musí být i argumenty metod typu T.
_________________
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Zobrazit příspěvky z předchozích:   
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> C / C++ Časy uváděny v GMT + 1 hodina
Jdi na stránku Předchozí  1, 2, 3, 4  Další
Strana 3 z 4

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra
Nemůžete odpovídat na témata v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete hlasovat v tomto fóru


Powered by phpBB © 2001, 2005 phpBB Group


Vzhled udelal powermac
Styl "vykraden" z phpBB stylu MonkiDream - upraveno by rezna