"Kioptimalizálja" a C++ a változómat. Mit okozhatja?

 ( emberk | 2008. február 13., szerda - 14:40 )

(bocsi de valamiért nincs hosszú i betüm)
Egy klaszterező (meg az alakját is .... ) detektáló algoritmost irok.

Ha "c++ -O0 teszt.cpp" vel forditok akkro a kimenet

A/Az 1802. megtalalt kaszter 2 darab reszecskebol all.
A/Az 1803. megtalalt kaszter 1 darab reszecskebol all.
A/Az 1804. megtalalt kaszter 1 darab reszecskebol all.
A/Az 1805. megtalalt kaszter 1 darab reszecskebol all.
A/Az 1806. megtalalt kaszter 3 darab reszecskebol all.
A/Az 1807. megtalalt kaszter 1 darab reszecskebol all.
A/Az 1808. megtalalt kaszter 1 darab reszecskebol all.
A/Az 1809. megtalalt kaszter 2 darab reszecskebol all.
A/Az 1810. megtalalt kaszter 2 darab reszecskebol all.
A/Az 1811. megtalalt kaszter 1 darab reszecskebol all.
különbözö méretek:776 klaszterek_száma:1811

Ha pedig "c++ -O1 teszt.cpp" vagy bagyobb O2 O3 akkor ez.
A/Az 1795. megtalalt kaszter 1 darab reszecskebol all.
A/Az 1796. megtalalt kaszter 1 darab reszecskebol all.
A/Az 1797. megtalalt kaszter 2 darab reszecskebol all.
A/Az 1798. megtalalt kaszter 2 darab reszecskebol all.
A/Az 1799. megtalalt kaszter 1 darab reszecskebol all.
különbözö méretek:0 klaszterek_száma:1799

Minden paraméter tök ugyanaz.

Jó lenne optimalizálni, mert elég jelentős sebességkölönbséget kapok.
Ezt mi okozhatja?

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

bugos a programod, majdnem biztos, hogy egy valtozot nem inicializalsz

debug modban altalaban inicializalja a valtozokat automatikusan, valami fix mintaval, pl. 0xab, release -ben meg memoria szemet van ott.

Aha akkor a hiba az én rendszeremben van ok kösz átnézem.

Esetleg próbáld ki a -Wall kapcsolót, hátha kapsz olyan warning-ot, ami segít a hiba megtalálásában.

M.

Köszi a probléma megoldva. Hasznos ez a -Wall. Egy darab nevű változó inicalizálatlan maradt. (helyesebben később kap értéket, de az nem a legjobb ott, mert addigra már átmegy egy if-en).

A -Wall mellet erdemes me'g -O3-at is megadni, mert az me'g egy adag warningot elohoz, ami egyebkent nem jonne elo".

Rendben van ezzel is jól működik. Közben kipróbáltam XXGDB-vel szerinte is ok. Mehet teszt alá. :) Köszönöm szépen mindenkinek.

-O3? tudtommal nem erdemes vele forditani, mert a gcc ilyen szintu optimalizacio mellett bugos (bar ffmpegnel is ez a default optim level)

-W -Wall nem eleg? :)

Nem bugos, csak nem egyértelműen gyorsabb mint az O2, viszont esetleg sokkal nagyobb kódot generál.

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

http://www.gentoo.org/doc/en/gcc-optimization.xml

"Compiling all your packages with -O3 will result in larger binaries that require more memory, and will significantly increase the odds of compilation failure or unexpected program behavior (including errors)."

Ez inkább vélemény, mint tény, vagy méginkább pillanatnyi állapot.

Az O3 működéséből adódóan nagyobb kódot generál.
Ez néha gyorsabb, de gyakran nem,

Minden más bug. Amit vélhetően szoktak javítgatni. Maximum nem ezek a bugok az elsők. De sehol nincs leírva, hogy az O3 dedikáltan bugos...

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

a bugosság nyilvánvalóan nem cél, hanem eredmény

a gcc ilyen szintu optimalizacio mellett bugos
Igen, en is sokszor hittem ezt. Aztan kiderult, hogy megiscsak en vagyok a hulye...:]

-W -Wall nem eleg?
Neha ez kicsit bosszanto is, pl kell melle' a -Wno-long-long. Igaz, a longlong mindig olyan kontextusban kerult elo nekem, ami vegul kulturtipussal archfuggetlenul ki lehetett valtani (size_t, off_t, ...), de ha tenyleg elesben kell direkt longlong, akkor ez szopo.

Ami meg hasznos hordozhatosag szempontbol az a -pedantic es/vagy -ansi.

Rakj fel egy valgrind-et és nézd meg azzal (csak ne felejtsd el előtte debugosra fordítani):

c++ -Wall -ggdb3 -o teszt teszt.cpp
valgrind --leak-check=full --show-reachable=yes --trace-children=yes --log-file=/tmp/teszt.log ./teszt ize hoze 42

Ezután a '/tmp/teszt.log.$PID'-ben keress ilyesmit:

==7972== Conditional jump or move depends on uninitialised value(s)
==7972==    at 0x4068044: vfprintf (in /lib/tls/libc-2.3.6.so)
==7972==    by 0x4070402: printf (in /lib/tls/libc-2.3.6.so)
==7972==    by 0x80483A6: main (teszt.c:10)

A hívási verem jelzi, hogy honnan jön inicializálatlan érték.

A topichoz nincs elsőkörben köze, de ez a topic segített megoldani a problémámat, ezért leírom,
hátha valaki más is belefut!

Szituáció (egyszerűsitve):

a.c

float szamol()
{
  ...
  return 1.26;
}

b.c

  float b = szamol();
  printf("%f\n, b);

eredmény: 42.0

kb két napja keresem, hogy miért nem jó a számolási eredmény!

megoldás: _mindenképp_ meg kell adni b.c -ben az a.c beli függvény
deklarációját (#include "a.h", vagy extern float szamol()), különben
nem tudja visszaadni a helyes értéket ...

már csak azt nem értem, hogy miért pont 42? :)))

Persze hogy meg kell adni, mert kulonben nem tudja a kisujjabol kiszopni, hogy mi a mennydorgos istennyila az a szamol(). Ugyanis nem tud magyarul szegeny. extern szuksegtelen, csak deklaralni kell.

illetve azt hiszem alapbol int-nek veszi a visszateresi erteket es ha nem az, akkor van szopo.

- Use the Source Luke ! -

Az. Ezert kell -Wall -pedantic -O3-mal forditani kapasbol mindent, mert az effele trivialis hibakat kiszurja...:]

A.