.[ ČeskéHry.cz ].
Matrix class - spravnost kodu
Jdi na stránku 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
perry



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

PříspěvekZaslal: 9. únor 2011, 19:10:02    Předmět: Matrix class - spravnost kodu Odpovědět s citátem

Zdravím,

začal jsem s C++ (přechod od C#, dříve jsem něco málo kutil v ANSI C). Začal jsem psát malou matematickou "knihovnu" pro použití v mých projektech (přeci jenom, je to základ).

Zajímalo by mě, zda je to dobře napsané a není-li to totální "prasečina", popř. co byste změnili

Matrix4x4.h

Děkuji za názory
_________________
Perry.cz
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: 9. únor 2011, 19:28:46    Předmět: Odpovědět s citátem

Pár rychlých postřehů neodborníka (i když jsem si taky už třídu pro matici napsal):
- inline se už tuším nemusí používat, moderní kompilery ho ignorují a inlinují dle libosti
- proč neděláš identity už v konstruktoru?
- kde máš operator[]?
- proč nemáš matici v poli?
- zdá se mi, že do téhle třídy chceš nacpat všechno - ale správný program není hotový tehdy, když není co přidat, ale když není co odebrat Wink
- osobně preferuji mít class a externy v .h a všechny funkce a proměnné v .cpp, které neincluduješ. Tak se vyhneš vícenásobnému nalinkování (což je hrůza Shocked ). A taky je asi vhodnější #pragma once místo #ifndef...#define...#endif (je to jednodušší napsat Smile ) - pokud tedy nepotřebuješ např. kontrolovat, zda je dodrženo pořadí includování apod.
_________________
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: 9. únor 2011, 19:44:19    Předmět: Odpovědět s citátem

- Ty inline jsou tam kvůli template... s nimi mi to nejde rozdělit do *.h a *.cpp.. viděl jsem sice řešení s extren keywordem, ale údajně to nepodporuje každý překladač.

- no, ne každou matici potřebuju jako identity Smile... ale stojí za zvážení, díky
- Smile diky, na ten jsem jaksi zapomnel
- v poli to nemám, protože mi někdo říkal, že použít proměnné je rychlejší pro jednotkový přístup, než sapisovat v random pořadí do pole.. ale težko říct co je na tom pravdy
- nacpat všechno ? Zatím tam není nic, co bych nepotřeboval Wink (kromě možná pár operátorů, ale ty radši píšu předem všechny)
- zvyk z ANSI C, kde #pragma nebylo Smile

Jinak díky za postřehy
_________________
Perry.cz
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
frca



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

PříspěvekZaslal: 9. únor 2011, 19:57:46    Předmět: Odpovědět s citátem

perry napsal:
- v poli to nemám, protože mi někdo říkal, že použít proměnné je rychlejší pro jednotkový přístup, než sapisovat v random pořadí do pole.. ale težko říct co je na tom pravdy

Toto je nějaká blbost. V paměti to bude uložené stejně, jako by to bylo statické pole, takže tam neurychlíš nic.
_________________
www.FRANTICWARE.com
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
perry



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

PříspěvekZaslal: 9. únor 2011, 20:14:54    Předmět: Odpovědět s citátem

Dobře.. přehodím to na pole...
_________________
Perry.cz
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: 1050

PříspěvekZaslal: 9. únor 2011, 20:33:40    Předmět: Odpovědět s citátem

perry napsal:
viděl jsem sice řešení s extren keywordem, ale údajně to nepodporuje každý překladač.
- v poli to nemám, protože mi někdo říkal, že použít proměnné je rychlejší pro jednotkový přístup, než sapisovat v random pořadí do pole.. ale težko říct co je na tom pravdy

ja som toto googlil. (template v cpp) a nasiel som ze extern template podporuju asi dva uplne exoticke prekladace. ale nie su to ICC, gcc ani ten vo Visual. implementovat to je vraj strasny opruz.

na 99% to prekladac prelozi cez LEA

a naco tam mas to #pragma region.
_________________
Najjednoduchšie chyby sa najtažšie hľadajú.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
if.then



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

PříspěvekZaslal: 9. únor 2011, 20:35:53    Předmět: Odpovědět s citátem

Pole si vlastně v C můžeš představit jako x elementů přesně po sobě. x[i] je vlastně "*(x+i)". Takže rychlost je asi fakt dost podobná jako u prvků uložených bez pole...

BTW: A není to trošku blbost, dělat si template matici? Vždyť v hrách budeš na 99% používat jen float nebo jen double, proč si přidělávat práci?
_________________
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
rezna



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

PříspěvekZaslal: 9. únor 2011, 20:46:44    Předmět: Odpovědět s citátem

ja bych varoval pred #pragma once - je to M$ specific AFAIK ikdyz dneska i GCC to prelozi s nejakym prepinacem - a navic to ma taky sva uskali
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
perry



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

PříspěvekZaslal: 9. únor 2011, 20:54:51    Předmět: Odpovědět s citátem

#pragma region tam je na uzavirani bloku (obdoba #region ze C#), má význam jen ve VC++

Ad templates: ve hrách je to jasný float (možná double), ale raději píšu věci co nejvíc univerzální, než abych je psal pořád dokola Smile. Mohl bych to sice řešit přes #define, ale takhle mi to přijde nějak lepší Smile

citace:

ja bych varoval pred #pragma once - je to M$ specific AFAIK ikdyz dneska i GCC to prelozi s nejakym prepinacem - a navic to ma taky sva uskali


Aha, možná proto nám to bylo v C řečeno kdysi #pragma once nepoužívat


Add pole: Mám použít definici T data[16] nebo T data[4][4] ? [/code]
_________________
Perry.cz
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Fila



Založen: 31. 07. 2007
Příspěvky: 853

PříspěvekZaslal: 9. únor 2011, 21:14:30    Předmět: Odpovědět s citátem

frca napsal:
perry napsal:
- v poli to nemám, protože mi někdo říkal, že použít proměnné je rychlejší pro jednotkový přístup, než sapisovat v random pořadí do pole.. ale težko říct co je na tom pravdy

Toto je nějaká blbost. V paměti to bude uložené stejně, jako by to bylo statické pole, takže tam neurychlíš nic.

Pokud s tim polem nedelas nejake skopiciny a ma pevnou velikost, pak by si s nim kompilator mel poradit stejne efektivne, jako se samostatnyma promennyma. Obecne to ale platit nemusi, v pameti to totiz vubec nemusi byt v prubehu vypoctu ulozene po celou dobu stejne (floatovou promennou muzes drzet nejakou dobu v registru, zatimco u pole si pri prasactejsim kodu napr. nemusi byt kompilator jisty, jestli muze nejaky udaj drzet v registru, nebo mu jej meni jina cast vypoctu, pak se musi valet nejlip v L1 a to rozhodne pomalejsi je).
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
rezna



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

PříspěvekZaslal: 9. únor 2011, 21:16:02    Předmět: Odpovědět s citátem

a hlavne bych se vyprnul na sabloni - psat nejuniverzalnejsi kod co to jde je super - ale az to opravdu potrebujes - takto si zbytecne do zacatku pridavas tuny balastu, ktery treba ani nikdy nebudes potrebovat
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
VladR



Založen: 30. 07. 2007
Příspěvky: 1322
Bydliště: Greater New York City Area

PříspěvekZaslal: 9. únor 2011, 22:04:43    Předmět: Odpovědět s citátem

pragma #once je prasacina, to nepouzivaj. Raz by si to omylom mohol pouzit v robote a vyrobis si pruser.

citace:
v poli to nemám, protože mi někdo říkal, že použít proměnné je rychlejší pro jednotkový přístup, než sapisovat v random pořadí do pole.. ale težko říct co je na tom pravdy

No ale to je hodne vytrhnute z kontextu. Tuna mas predsa pole o 16 konsekutivnych hodnotach. De facto cele to bude cely cas v L1ke (za predpokladu spravneho zarovnania - hod si tam align ()).


To, ze ty pouzijes premennu, ktoru zadeklarujes v metode, a teda bude na stacku vobec nezarucuje, ze kompiler ju hodi do registru. A aj ked obvykle lokalne premenne skoncia v L1ke, zarucene to uplne nemas, pokial fakt nevies co presne robis.

Ak chces takuto kontrolu, tak potom rovno chod do SSE, a tam to mas na par instrukcii.

Za dalsie - skontroluj, ci nahodou niekde nemas preklepom typecast double->float

Tiez uvedom si, ze execution units vedia paralelne zratat viac vysledkov, takze ak vies zreorganizovat dependencies manualne (a pomoct tak kompileru), tak nevahaj a sprav to.
Napr. add zaberie 3 clocky, ale pipeline vie efektivne zacat novu floatingpoint operaciu kazdy clock, pokial nezavisi na vysledku predoslej. Inak, dostanes vysledok len kazdy treti clock (namiesto kazdeho za predpokladu nulovej dependency na predoslom vysledku).

Tento paralelizmus totalne zabijes tym, ak zadeklarujes lokalne parametre, ktore si bude CPU cucat zo stacku - lebo tym implicitne zavedies dependency (aj ked z L1 cache, ale to uz execution units zily netrha).


Samozrejme, paralelizmus sa najlepsie kontroluje na urovni assembleru, kde si vies rucne prehodit priamo nesuvisiaci integer kod medzi floatingpoint kod, cim zarucis paralelizmus na urovni jak integer execution CPU units, tak floatingpoint execution CPU units bez akychkolvek stalls. To je ale uz cisty assembler a pokial rychlost nie je kriticka, tak sa tym ani zaoberat nemusis.


Cache funguje najefektivnejsie, ak pristupujes k datam sekvencne, menej efektivne ak ides spatne a uplne najhorsie pri random pristupe.

Ak by si robil s SSE, tak si vies priamo poziadat o cache line prefetch.
Tuna pozor este na uncached write - pretoze cela cache line musi byt precitana a zapisana.

Este by som podotkol, ze sa netreba bat pripadneho prepnutia z L1 do L2.Na Core2Duo je latency pri L1ke 3 clocks, a pri L2ke 14 clocks, co je stale obrovsky rozdiel oproti ~185 clocks z RAMky.


Kod teraz nemam cas pozerat, takze pisem len take bezne, vseobecne rady.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
perry



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

PříspěvekZaslal: 9. únor 2011, 22:08:21    Předmět: Odpovědět s citátem

Tak tuny balastu mi nevadi (jediné co mi vadí, je ta matlanina, kdy nejde nějak čistě držet *.h a *.cpp strukturu)...
a co jsem četl, tak výkon šablonama netrpí... hlavni cil byl spis je vyzkoušel, protože jsem je pak chtěl aplikovat až budu psát stromy, kde mi přijdou jako podstatná a užitečná věc

Ad pole vs proměnné:
Když bych nechal proměnné a chtěl bych případně poslat matici do shaderu jako raw data, tak tam už výkon ztratím při konverzi na pole ? Nebo můžu vzít matici a poslat její obsah v proměnných do shaderu ve stylu
kód:
Matrix4x4<float> mojeMatice = Matrix4x4<float>::Identity();
send_raw_data(mojeMatice)

Zase... možná je to nějaká prasečina, ale C# tohle interpretuje a funguje to OK Smile
_________________
Perry.cz
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
VladR



Založen: 30. 07. 2007
Příspěvky: 1322
Bydliště: Greater New York City Area

PříspěvekZaslal: 9. únor 2011, 22:12:47    Předmět: Odpovědět s citátem

perry napsal:
Add pole: Mám použít definici T data[16] nebo T data[4][4] ?
Kludne pouzi aj [4][4], len si potom daj pozor, aby si pri pripadnom traversovani vo vnorenom cykle mal ten druhy index meneny v tom vnorenom cykle - nech to zodpoveda poradiu, ako je to aj skutocne v RAMke - kvoli cache.

iste, pri 16 hodnotach je to sumafuck, ale je dobre na to mysliet.

Traversovat maticu tak, ze druhy index menis v prvom cykle je proste fuuuuuj a taky clovek by mal radsej ist "kodit" databazy Very Happy
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
VladR



Založen: 30. 07. 2007
Příspěvky: 1322
Bydliště: Greater New York City Area

PříspěvekZaslal: 9. únor 2011, 22:18:00    Předmět: Odpovědět s citátem

perry napsal:

Ad pole vs proměnné:
Když bych nechal proměnné a chtěl bych případně poslat matici do shaderu jako raw data, tak tam už výkon ztratím při konverzi na pole ? Nebo můžu vzít matici a poslat její obsah v proměnných do shaderu ve stylu
kód:
Matrix4x4<float> mojeMatice = Matrix4x4<float>::Identity();
send_raw_data(mojeMatice)

Zase... možná je to nějaká prasečina, ale C# tohle interpretuje a funguje to OK Smile
Netusim ako to C# runtime interpretuje, nevidel som ten kod.
Ale ak posielas maticu do shaderu, tak predsa davas adresu pola a velkost.
Toto s premennymi nespravis.
Druha vec je, ze ten shader tak casto volat nebudes, takze ten overhead nebude tak strasny.

No ale prasacina to bude v kazdom pripade Smile
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
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 1, 2, 3, 4  Další
Strana 1 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