Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: Onestone 23. 02. 2017, 19:14:17
-
Zdravím, potřeboval bych poradit nebo popostrčit správným směrem. V rámci ročníkového projektu píšu simulátor částic. Algoritmus správně funguje a jen se jej snažím urychlit. Všimnul jsem si, že na Skylake i7 není AVX rychlejší než SSE, i když používá dvojnásobnou šířku vektorů. Nejsem primárně programátor, tak neznám detaily, v čem může být zádrhel?
-
Ahoj, sice ti přímo neporadím, ale zajímá mne, co děláš.
V čem to píšeš? Počítáš i s kolizemi a zachováním hybnosti a momentu hybnosti? Se silovými poli, nebo bez? Díky.
-
Hodně záleží na tom, jak přistupujete do paměti (a jak často se netrefíte do obsahu, který není v Lx cache) a jak moc náročné je nastrkat data to vektorů, se kterými pak provedete dané operace.
Pokud provádíte náhodné přístupy do paměti, data pravděpodobně nebudou v cache, takže budete ztrácet výkon na čekání, než se natáhnou z hlavní paměti. Dobré je snažit se shlukovat přístupy do blízkých míst k sobě, případně se snažit do paměti přistupovat lineárně (procesor pak přístupy umí předvídat).
Pokud spotřebujete příliš času na to, abyste data dostal do vektorů, samotné urychlení vektorových operací se nemusí projevit. Málokdy se podaří zrychlení shodné s délkou vektorů (např. 8 pro práci s 32bitovými celými čísly na AVX, 4 pro SSE). Dobré je také vektorový a nevektorový kód příliš do sebe nemíchat, ať se nemusí data přenášet mezi vektorovými a obecnými registry. Také může pomoci vyhnout se podmínkám (někdy to lze zařídit pomocí série ANDů, NOTů a podobných operací). Jestli ale pracujete z floaty/doubly, bude to o dost horší.
Pokud je vaše aplikace vícevláknová a běží na NUMA stroji, je tu opět další zdroj problémů – přístup do různých částí paměti není stejně drahý.
-
Zdravím, potřeboval bych poradit nebo popostrčit správným směrem. V rámci ročníkového projektu píšu simulátor částic. Algoritmus správně funguje a jen se jej snažím urychlit. Všimnul jsem si, že na Skylake i7 není AVX rychlejší než SSE, i když používá dvojnásobnou šířku vektorů. Nejsem primárně programátor, tak neznám detaily, v čem může být zádrhel?
co takhle to běžet na grafické kartě ?
co se týče SIMD, nemám námitek, ale na 32 bit double bude GPU nejrychlejší řešení.
druhá otázka, používáš raw SIMD instrukce někde v inline asm a nebo máš knihovnu ? Pokud to druhý, možná by stálo za to vyzkoušet jich víc ...
-
co takhle to běžet na grafické kartě ?
Presne, pokud mate i7 se zabudovanym GPU Intel 530 nebo 630 tak tam bude pocitani vektoru diky masivnejsi paralelizaci jiste vykonne. Na druhou stranu integrovane GPU pouzivaji hlavni pamet a to bude zase brzda pokud to nebude optimalizovano na co nejmensi pristup k pameti.
-
Ahoj, sice ti přímo neporadím, ale zajímá mne, co děláš.
V čem to píšeš? Počítáš i s kolizemi a zachováním hybnosti a momentu hybnosti? Se silovými poli, nebo bez? Díky.
Ahoj, jo, s tím vším se počítá, o kolize jde především. Píšu to v C++ a to nejnutnější v asm (pro ARM a Intel64), možná zkusím i OpenCL, ale to je asi slepá ulička.
-
co takhle to běžet na grafické kartě ?
Presne, pokud mate i7 se zabudovanym GPU Intel 530 nebo 630 tak tam bude pocitani vektoru diky masivnejsi paralelizaci jiste vykonne. Na druhou stranu integrovane GPU pouzivaji hlavni pamet a to bude zase brzda pokud to nebude optimalizovano na co nejmensi pristup k pameti.
Mám Radeon Pro 460, ale má jen 4GB RAM. Pro malé instance to stačí, ale přenosy dat do paměti to výkonostně zabíjejí. Navíc to potřebuju i pro Xeony bez GPU, takže spíš tíhnu k AVX512.
-
Začni tím, že zjistíš, kde to opravdu drhne: http://valgrind.org/docs/manual/cl-manual.html
Callgrind umí profilovat i cache a branch prediction. Až potom má teprve smysl řešit mikrooptimalizace typu jesti SSE nebo AVX.
-
Existuje i bridge OpenCL / CUDA pro ne-nvidia GPU https://github.com/hughperkins/cuda-on-cl mozna prostudovat ty zdrojaky bude k necemu dobre
-
Nazdar, odporucam ti pozriet CPU blog od Agnera Foga:
http://www.agner.org/optimize/blog/
(nieco o Skylake: http://www.agner.org/optimize/blog/read.php?i=415)
A dalej si pozri Optimization manuals:
http://www.agner.org/optimize/#manuals
odporucam pozriet hlavne tieto dva:
"Optimizing subroutines in assembly language"
a
"Instruction tables: Lists of instruction latencies, throughputs and micro-operation breakdowns for Intel, AMD and VIA CPUs"
s pozdravom Juraj
-
Ahoj, jo, s tím vším se počítá, o kolize jde především. Píšu to v C++ a to nejnutnější v asm (pro ARM a Intel64), možná zkusím i OpenCL, ale to je asi slepá ulička.
OpenCL není slepá ulička, dělal jsem v tom pár projektů a jelo to v pohodě. Dobrý je na tom to, že jsi schopen tam manipulovat s OpenGL vektory, takže pokud ten výsledek výpočtů používáš jen na zobrazení uživateli (co částice, to tečka v prostoru), je možné se jednoduše vyhnout opakovanému kopírování dat mezi GPU a CPU ( https://software.intel.com/en-us/articles/opencl-and-opengl-interoperability-tutorial ).
Akorát bych tě měl upozornit že jestli máš nVidii, tak tam týpkové udělali pár "chytáků". Pokud budeš mít kernel moc složitý, bude se ti nehorázně sekat "plocha". Pokud ti celkový výpočet rangekernelu bude překračovat několik sekund (okolo 6ti), tak tě vyjebne s nic neříkající hláškou (toto lze řešit přes global_work_offset/global_work_size). U Intelu nic takového nepozoruju.
-
Dalsi moznosti, hlavne pro vetsi modely je cloudova CUDA od Googlu
https://cloudplatform.googleblog.com/2017/02/GPUs-are-now-available-for-Google-Compute-Engine-and-Cloud-Machine-Learning.html
Cena je 0.77$ za hodinu strojoveho casu na konfiguraci z rise snu (az do 20000 jader v osmi Teslach).
-
Nazdar, odporucam ti pozriet CPU blog od Agnera Foga:
http://www.agner.org/optimize/blog/
(nieco o Skylake: http://www.agner.org/optimize/blog/read.php?i=415)
A dalej si pozri Optimization manuals:
http://www.agner.org/optimize/#manuals
odporucam pozriet hlavne tieto dva:
"Optimizing subroutines in assembly language"
a
"Instruction tables: Lists of instruction latencies, throughputs and micro-operation breakdowns for Intel, AMD and VIA CPUs"
s pozdravom Juraj
Zajímavé odkazy, dík.
-
Ahoj, jo, s tím vším se počítá, o kolize jde především. Píšu to v C++ a to nejnutnější v asm (pro ARM a Intel64), možná zkusím i OpenCL, ale to je asi slepá ulička.
OpenCL není slepá ulička, dělal jsem v tom pár projektů a jelo to v pohodě. Dobrý je na tom to, že jsi schopen tam manipulovat s OpenGL vektory, takže pokud ten výsledek výpočtů používáš jen na zobrazení uživateli (co částice, to tečka v prostoru), je možné se jednoduše vyhnout opakovanému kopírování dat mezi GPU a CPU ( https://software.intel.com/en-us/articles/opencl-and-opengl-interoperability-tutorial ).
Akorát bych tě měl upozornit že jestli máš nVidii, tak tam týpkové udělali pár "chytáků". Pokud budeš mít kernel moc složitý, bude se ti nehorázně sekat "plocha". Pokud ti celkový výpočet rangekernelu bude překračovat několik sekund (okolo 6ti), tak tě vyjebne s nic neříkající hláškou (toto lze řešit přes global_work_offset/global_work_size). U Intelu nic takového nepozoruju.
V mém případě je OpenCL no go, musím kopírovat data na Radeon Pro, už mám ověřeno, že to je bottleneck.
-
Všimnul jsem si, že na Skylake i7 není AVX rychlejší než SSE
To platí ale jen u některých instrukcí (div, sqrt, vcvttpd2dq, atd) a přesouvání mezi LO/HI (permutace, broadcast, ale i např. `vpsrlw y, y, x`), u ostatních rozdíl mezi XMM|YMM není.
Příklad (čísla jsou nezaokrouhlené, je to +-):
vpmovsxdq xmm, xmm : Lat: 0.96 Rcp: 0.96
vpmovsxdq ymm, xmm : Lat: 2.86 Rcp: 0.96
vpsrlq xmm, xmm, i8 : Lat: 0.96 Rcp: 0.48
vpsrlq ymm, ymm, i8 : Lat: 0.96 Rcp: 0.48
vpsrlq xmm, xmm, xmm : Lat: 1.91 Rcp: 0.96
vpsrlq ymm, ymm, xmm : Lat: 3.82 Rcp: 0.96
vpunpckhbw xmm, xmm, xmm : Lat: 0.96 Rcp: 0.96
vpunpckhbw ymm, ymm, ymm : Lat: 0.96 Rcp: 0.96
vrsqrtps xmm, xmm : Lat: 3.82 Rcp: 0.96
vrsqrtps ymm, ymm : Lat: 3.82 Rcp: 0.96
vsqrtpd xmm, xmm : Lat:12.41 Rcp: 4.65
vsqrtpd ymm, ymm : Lat:12.41 Rcp: 9.07
vsqrtps xmm, xmm : Lat:11.45 Rcp: 2.86
vsqrtps ymm, ymm : Lat:11.45 Rcp: 5.73
vsqrtsd xmm, xmm, xmm : Lat:12.41 Rcp: 4.30
vsqrtss xmm, xmm, xmm : Lat:11.45 Rcp: 2.86
vsubpd xmm, xmm, xmm : Lat: 3.82 Rcp: 0.64
vsubpd ymm, ymm, ymm : Lat: 3.82 Rcp: 0.64
vsubps xmm, xmm, xmm : Lat: 3.82 Rcp: 0.64
vsubps ymm, ymm, ymm : Lat: 3.82 Rcp: 0.64
vmulpd xmm, xmm, xmm : Lat: 3.82 Rcp: 0.64
vmulpd ymm, ymm, ymm : Lat: 3.82 Rcp: 0.64
vmulps xmm, xmm, xmm : Lat: 3.82 Rcp: 0.64
vmulps ymm, ymm, ymm : Lat: 3.82 Rcp: 0.64
vhaddpd xmm, xmm, xmm : Lat: 5.73 Rcp: 1.91
vhaddpd ymm, ymm, ymm : Lat: 5.73 Rcp: 1.91
vhaddps xmm, xmm, xmm : Lat: 5.73 Rcp: 1.91
vhaddps ymm, ymm, ymm : Lat: 5.73 Rcp: 1.91
vxorpd xmm, xmm, xmm : Lat: 0.96 Rcp: 0.32
vxorpd ymm, ymm, ymm : Lat: 1.00 Rcp: 0.34
vinsertf128 ymm, ymm, xmm, i8 : Lat: 2.86 Rcp: 0.96
vinserti128 ymm, ymm, xmm, i8 : Lat: 2.86 Rcp: 0.96
Tabulky od Agner Fog jsou dobrý start, ale při vlastním měření jsem zjistil, že nejsou úplně přesné.
-
Ja bych uplne tu grafiku nezavrhoval.
Wiki https://en.wikipedia.org/wiki/Molecular_modeling_on_GPUs (https://en.wikipedia.org/wiki/Molecular_modeling_on_GPUs)
GTX1070 umi host<->device pres 1500 MB/s, pokud je to malo, cim mene bude pocitat CPU, tim mene se musi data kopirovat.
Gugl ted nedavno louskl sha1 (clanek tu na root) a taky to nedelali na CPU.
Ovsem jak to napatlate v ASM, uz to nikdo nespravi.
-
Tak pomohl prefetching, ale obecně na různých procesorech se to chová různě. GPU je o ničem, na Radeonu Pro se dostanu na rychlost CPU, jinak to je obecně horší. Možná ještě zkusit Metal místo OpenCL.
-
Jestli mate nejakej test, prozenu to tou nvidii, ať mate srovnání