sh-3.2$ time ./ray-g++-64
15.21% Output has been written to tracement.tga
20.95% Output has been written to tracement.tga
25.98% Output has been written to tracement.tga
30.49% Output has been written to tracement.tga
41.46% Output has been written to tracement.tga
49.24% Output has been written to tracement.tga
53.96% Output has been written to tracement.tga
57.23% Output has been written to tracement.tga
61.35% Output has been written to tracement.tga
66.72% Output has been written to tracement.tga
80.49% Output has been written to tracement.tga
91.97% Output has been written to tracement.tga
98.14% Output has been written to tracement.tga
freeNode(0)
real 2m4.428s
user 8m12.798s
sys 0m0.803s
sh-3.2$ time ./ray-icpc-64
21.14% Output has been written to tracement.tga
33.74% Output has been written to tracement.tga
52.56% Output has been written to tracement.tga
61.38% Output has been written to tracement.tga
80.88% Output has been written to tracement.tga
99.10% Output has been written to tracement.tga
freeNode(0)
real 0m55.223s
user 3m35.516s
sys 0m0.737s
sh-3.2$
Fordítási paraméterek:
g++ -O3 -march=nocona
icpc -fast
(64 bites kódról van szó, természetesen mindkét esetben.)
A C++ program négy szálon dolgozik, amit pthread-del old meg.
A futtató processzor egy Core 2 Quad (Q6600) 2,4GHz-en, 800MHz-es RAM-okkal.
Remélem nem hagytam ki semmi fontos információt.
- Kodest blogja
- A hozzászóláshoz be kell jelentkezni
- 1144 megtekintés
Hozzászólások
gondolom van benne vektormuvelet rendesen, de kezzel irt asm kod meg nincs. a gcc defaultbol nem hasznal mmx/sse-t ehhez, az intel compiler igen. igy nem csoda az ekkora kulonbseg...
eleg sok kapcsoloja van mindket forditonak, celszeru lenne eloszor az adott forditot a sajat kapcsoloival "versenyeztetni" (megkeresni hogy pl.. a gcc cmilyen opciokkal forditja a leggyorsabb kodot). ezutan lehetne a 2 progit egymasnak engedni.
amugy gcc-bol van sokkal ujabb is. egy probat meger.
A'rpi
- A hozzászóláshoz be kell jelentkezni
Van sok vektormuvelet, igen, viszont nincs asm egyaltalan.
Szerintem ebbol a 4.1.2-es gcc-bol mar nem lehet sokkal tobbet kihozni. Tudom, hogy nem egy mai verzio, de most azokat a forditokat teszteltem, amik reszei a Gentoo stabil aganak. Probaltam -msse{,2,3} kapcsolokat hozzadni, de pontosan ugyanazt a binarist forditotta mint azok nelkul. A manbol pedig kiderult, hogy a 64 bites gcc-ben ezek alapertelmezettek sok mas optimalizalo opcioval egyutt. Probaltam a -ftree-vectorize-ot is, de ettol sem lett gyorsabb. Meg fogom nezni az ujabb gcc-t is (4.3), mert abban van nehany igeretes dolog [ http://gcc.gnu.org/projects/tree-ssa/vectorization.html ].
Erdekes, hogy az inteles forditoval forditott valtozat majdnem annyival gyorsabb, mint amennyivel nagyobb meretu maga a futtathato :]
- A hozzászóláshoz be kell jelentkezni
-mfpmath=sse ?
-funsafe-math-optimizations ?
-ffast-math ?
- A hozzászóláshoz be kell jelentkezni
Az altalad megadott opciokkal gatlastalanul leteszteltem, bar hozza kell tenni par megjegyzest. Eloszor is az eredmenyek:
real 2m6.494s
user 8m17.208s
sys 0m1.207s
A megjegyzesek, melyek magyarazatul szolgalnak:
* -mfpmath=sse: benne van a manban, hogy x86-64 eseten sse a default erre az opciora, i386 eseten pedig 387, tehat mar az optimalisabb megoldas van kivalasztva esetunkben az opcio megadasa nelkul is.
* -ffast-math: implikalja a -funsafe-math-optimizations-t
* -funsafe-math-optimizations: ettol vartam volna, hogy valamit javul, de ugy latszik nem segitett sajnos ez sem. Raadasul a man azzal fenyeget hogy nem ajanlott, mert elronthatja az eredmenyt.
GCC oldalrol nagyon ugy fest, hogy csak az ujabb valtozatok szorongathatjak meg az intel compiler-t. Amugy az intel compiler is 2007 vegi, abbol nem tudom milyen lehet a legfrissebb... (majd megnezem igy a 10.0 utan a 10.1-et is)
- A hozzászóláshoz be kell jelentkezni
Ha annyival nagyobb, akkor az ICC nem csinal alapbol loop unrollingot? (-funroll-loop gcc-ben)
- A hozzászóláshoz be kell jelentkezni
Az ICC a manja szerint kifejezetten az -O1-nel irja, hogy nem csinal loop unrolling-ot, ebbol arra kovetkeztetek, hogy -O2-re mar csinal, en pedig a -fast kapcsolo megadasaval automatikusan -O3-at hasznalok. Tehat itt mar az ICC valoszinuleg csinal loop unrolling-ot. A GCC viszont alapbol nem, ezert kiprobaltam a -funroll-loops kapcsolot.
Mivel az inteles warningokat elkezdtem kozben kigyomlalni, kicsit megvaltozott a kod (gyorsabb lett), ezert most ujra kozlom az eredmenyeket roviden:
g++ -O3 -march=nocona
Forditas utan futtatva a progit:
real 1m56.431s
user 7m39.900s
sys 0m1.327s
g++ -O3 -march=nocona -funroll-loops
(Lathatoan nagyobb lett a futtathato binaris: 52955 -> 57051)
Forditas utan futtatva a progit:
real 1m57.429s
user 7m40.097s
sys 0m1.163s
icpc -fast
Forditas utan futtatva a progit:
real 0m48.189s
user 3m9.544s
sys 0m0.927s
- A hozzászóláshoz be kell jelentkezni
-march mellett -mcpu -t is erdemes hasznalni, mert sokszor buta dolgokat tud kihozni nelkule.
Mindenesetre az impressziv, hogy az ICC mindenfele konfiguralas nelkul eleri ezt, de nem lehet, hogy cpuid alapjan tuningol az adott gepre? (ami termeszetesen cross compilingnal enyhen zavaro lenne)
- A hozzászóláshoz be kell jelentkezni
Az -mcpu a man szerint egy deprekalt opcio, es forditaskor a gcc is irja hogy ne hasznaljam. Nem az -mtune-ra gondoltal veletlenul?
- A hozzászóláshoz be kell jelentkezni
De mindegy is, mert -march=nocone es -mtune=nocona utan is:
real 1m57.482s
user 7m39.607s
sys 0m1.273s
A man szerint amugy a -march implikalja az -mtune-t.
Egyebkent az nem teljesen igaz, hogy az intel forditonak nem adtam infot a processzorrol, mivel a -fast implikalja a -xT -O3 -ipo -no-prec-div -static opciokat, amik kozul az -xT kivalasztja a processzorok kozul azt, hogy "Intel(R) Core(TM)2 Duo processors, Intel(R) Core(TM)2 Quad processors, and Intel(R) Xeon(R) processors with SSSE3". Tehat a -fast egy rovid opcio, de elegge testre van szabva nekem :]
- A hozzászóláshoz be kell jelentkezni
-static, akkor lehet a GCC alapbol PIC kodot fordit a gepedre, ami jelentosen csokkentheti a teljesitmenyt, felteve, ha hasznalsz libraryket.
Az -ipo szerintem a inliningon valtoztat, GCC-nel inline limit-et lehet valtoztatni. (-finline-functions -finline-limit=)
A -no-prec-div pedig FPU pontossagot csokkenti, erre is biztos van GCC-s alternativa. (-ffast-math)
Reference:
"
The -fast option enhances execution speed across the entire program by including the following options that can improve run-time performance:
-O3 (maximum speed and high-level optimizations)
-ipo (enables interprocedural optimizations across files)
-xT (generate code specialized for Intel(R) Core(TM)2 Duo processors, Intel(R) Core(TM)2 Quad processors and Intel(R) Xeon(R) processors with SSSE3)
-no-prec-div (disable -prec-div) where -prec-div improves precision of FP divides (some speed impact)
-static (statically link libraries during compilation)
"
- A hozzászóláshoz be kell jelentkezni
Na megvan a lenyeg. Felbontottam a -fast opciot azokra, amiket helyettesit, es egyenkent elkezdtem leszedegetni. Arra jutottam, hogy az -ipo levetele utan 50 masodperccel megugrott a futas ido, ami ugye 2 perces teljes futasidonel eleg jelentos valtozas :] Szoval ennek az -ipo dolognak erdemes utana nezni.
- A hozzászóláshoz be kell jelentkezni
Multi-file ip optimizations (-ipo) that includes:
- inline function expansion
- interprocedural constant propogation
- dead code elimination
- propagation of function characteristics
- passing arguments in registers
- loopinvariant code motion
Ebbol ket dolgot biztosan tud a GCC, az inline, amit fentebb irtam, es a pass-args-as-regs.
- A hozzászóláshoz be kell jelentkezni
Utana neztem mindkettonek:
- inline: -finline-functions: az -O3 maga utan vonja. Azert probalkoztam explicit megadni, de nem segitett. Emellett megneztem a -finline-limit-et is, ami a man szerint default 600. Ezt felvittem 10000-re, de nem jott a varva vart javulas.
- pass-args-as-regs: ezt igy szo szerint nem talaltam meg. Talaltam helyette olyat, hogy -mregparm=n, es -msseregparm. Na ezt nem implikalta semmilyen eddigi mas opcio, viszont a man azt mondja, hogy az osszes hasznalt libnek ugyanigy kell leforditva lennie, ami azt jelenti, nem tud olyat a gcc-4.1.2, hogy csak hazon belul (modulon belul) hasznal regparmot, ami talan nem is lenne olyan rossz otlet... Azert kiprobaltam, de sajnos az -mregparm=n (n=0..3) segfaultos programot forditott. Az -msseregparm mar nem szallt el, viszont gyorsabb sem lett a program tole.
- A hozzászóláshoz be kell jelentkezni
core2-re a gcc-4.3 tud optimalizálni. 4.1 csak PentiumD-re tud
gcc-4.3
[snip]
i386 and x86-64 Options -mtune=cpu-type -march=cpu-type
-mfpmath=unit -masm=dialect -mno-fancy-math-387 -mno-fp-ret-in-387
-msoft-float -mno-wide-multiply -mrtd -malign-double
-mpreferred-stack-boundary=num -mcld -mcx16 -msahf -mrecip -mmmx
--> -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -msse4 -msse4a
-m3dnow -mpopcnt -mabm -msse5 -mthreads -mno-align-stringops
-minline-all-stringops -mpush-args -maccumulate-outgoing-args
-m128bit-long-double -m96bit-long-double -mregparm=num
-msseregparm -mveclibabi=type -mpc32 -mpc64 -mpc80 -mstackrealign
-momit-leaf-frame-pointer -mno-red-zone -mno-tls-direct-seg-refs
-mcmodel=code-model -m32 -m64 -mlarge-data-threshold=num
-mfused-madd -mno-fused-madd
[snip]
debian gnu/linux @ linux-2.6.26-rc8-git2 | patch
info
- A hozzászóláshoz be kell jelentkezni