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

Založen: 28. 07. 2007 Příspěvky: 1561
|
Zaslal: 10. únor 2011, 13:45:19 Předmět: |
|
|
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 |
|
 |
nou

Založen: 28. 07. 2007 Příspěvky: 1051
|
Zaslal: 10. únor 2011, 14:24:52 Předmět: |
|
|
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 |
|
 |
frca

Založen: 28. 07. 2007 Příspěvky: 1561
|
Zaslal: 10. únor 2011, 14:31:18 Předmět: |
|
|
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 |
|
 |
if.then
Založen: 13. 04. 2008 Příspěvky: 579
|
Zaslal: 10. únor 2011, 14:40:02 Předmět: |
|
|
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 |
|
 |
perry

Založen: 28. 07. 2009 Příspěvky: 879
|
Zaslal: 10. únor 2011, 15:06:10 Předmět: |
|
|
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 |
|
 |
Tringi

Založen: 28. 07. 2007 Příspěvky: 290
|
Zaslal: 10. únor 2011, 15:35:13 Předmět: |
|
|
| Vilem Otte napsal: |
| 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á. |
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š  |
Až mi vysvětlíš ten overloading a proč pomalost konverze svádíš na static_cast, budu si možná myslet něco lepšího  _________________ WWW | GitHub | TW |
|
| Návrat nahoru |
|
 |
nou

Založen: 28. 07. 2007 Příspěvky: 1051
|
Zaslal: 10. únor 2011, 16:31:51 Předmět: |
|
|
| 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 |
|
 |
Tringi

Založen: 28. 07. 2007 Příspěvky: 290
|
Zaslal: 10. únor 2011, 16:37:09 Předmět: |
|
|
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).
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 |
|
 |
Vilem Otte

Založen: 18. 09. 2007 Příspěvky: 462 Bydliště: Znojmo - Sedlesovice, Kravi Hora
|
Zaslal: 10. únor 2011, 19:33:01 Předmět: |
|
|
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 |
|
 |
igor

Založen: 28. 07. 2007 Příspěvky: 196
|
Zaslal: 10. únor 2011, 19:54:49 Předmět: |
|
|
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 |
|
 |
Tringi

Založen: 28. 07. 2007 Příspěvky: 290
|
Zaslal: 10. únor 2011, 20:39:06 Předmět: |
|
|
Přesně tak, operátor je jen extra pojmenovaná funkce a syntaktický "cukr"
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 |
|
 |
Vilem Otte

Založen: 18. 09. 2007 Příspěvky: 462 Bydliště: Znojmo - Sedlesovice, Kravi Hora
|
Zaslal: 10. únor 2011, 22:02:13 Předmět: |
|
|
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
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 |
|
 |
perry

Založen: 28. 07. 2009 Příspěvky: 879
|
Zaslal: 11. únor 2011, 09:49:33 Předmět: |
|
|
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 ) ... 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 |
|
 |
rezna
Založen: 27. 07. 2007 Příspěvky: 2156
|
Zaslal: 11. únor 2011, 10:59:52 Předmět: |
|
|
@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 |
|
 |
Houp
Založen: 28. 07. 2007 Příspěvky: 672
|
Zaslal: 11. únor 2011, 12:04:15 Předmět: |
|
|
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 |
|
 |
|