#define n jakaś_liczba
int clamp(int x) {
if ((unsigned int)x > n) {
if (x < 0) return 0;
if (x > n) return n; // XXX
}
else
return x;
}
Stwierdziłem, że drugi if, oznaczony XXX, jest zbędny i lepiej tam
wrzucić else
if (x < 0) return 0;
else return n;
Gcc 3.4.4 po tej modyfikacji wyprodukował zdecydowanie krótszy kod. Dziś
sprawdziłem w gcc 4.4.cośtam - dla obu wersji kod wynikowy był identyczny
i odpowiadał temu lepszemu z 3.4.4. Jeszcze z ciekawości zamieniłem na
zwykłe porównania ten hack z rzutowaniem:
if (x < 0 || x > n) {
if (x < 0) return 0;
else return n;
}
return x;
Kod wynikowy bez zmian. Dopiero nieco gorzej poszło dla naiwnego:
if (x < 0) return 0;
else if (x > n) return n;
else return x;
w.
PS. zobaczcie, jak gcc realizuje operację x % stała.
--
Z humoru absurdalnego to już wolę Pietrzaka
>Kod wynikowy bez zmian. Dopiero nieco gorzej poszło dla naiwnego:
>
> if (x < 0) return 0;
> else if (x > n) return n;
> else return x;
W jakim sensie gorzej? Bo "naiwnie" ;-) patrzac jest tu jeden warunek
mniej.
milego dnia, hej
Zapewne dlatego, że najczęstszy przypadek (x zwracany bez zmian)
przechodzi przez dwa warunki a nie jeden. Bez optymalizacji kierowanych
profilowaniem (PGO) kompilator się raczej nie domyśli, że coś z drugiego
else jest przypadkiem najczęstszym.
pzdr
\SK
--
"Never underestimate the power of human stupidity" -- L. Lang
--
http://www.tajga.org -- (some photos from my travels)
> PS. zobaczcie, jak gcc realizuje operację x % stała.
tak jak jest optymalniej dla danych parametrów…
--
qo |) CPL<=dataDPL CPL==/>=codeDPL:conform'/nc';max=CPL! AV0ID bHp
_x/ , CPL<=TSS,gateDPL CPL>=/==dest_DPL:/(jmp&nc') ,RPL!- #GP -o0o
| ng __ -- __ -- __ -- __ -- __ -- __ -- __ -- __ -x86-, EV3RY o0o
,__ -- __ -- Current/Requested/DescriptorPrivilegeLevel C/R/DPL , d4y m:#=
--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---
> Kod wynikowy bez zmian. Dopiero nieco gorzej poszło dla naiwnego:
>
> if (x < 0) return 0;
> else if (x > n) return n;
> else return x;
gorzej w jakim sensie? ja otrzymalem kod bez skokow.
$ cat clamp.c
int const n = 13;
int clamp( int x)
{
if ( x < 0 ) return 0;
else if ( x > n ) return n;
else return x;
}
$ gcc clamp.c -O2 -S -Wall
$ cat clamp.s
(...)
clamp:
cmpl $13, %edi
movl $13, %edx
cmovle %edi, %edx
xorl %eax, %eax
testl %edx, %edx
cmovns %edx, %eax
ret
gcc-4.4.2-20091026 (x86_64)
> Zapewne dlatego, że najczęstszy przypadek (x zwracany bez zmian)
a jak do tego doszedles? Bo jezeli kazda liczba jest rownoprawdopodobna
to to jest najzadszy przypadek.
> Wojciech Muła wrote:
>
> > Kod wynikowy bez zmian. Dopiero nieco gorzej poszło dla naiwnego:
> >
> > if (x < 0) return 0;
> > else if (x > n) return n;
> > else return x;
>
> gorzej w jakim sensie? ja otrzymalem kod bez skokow.
Dwa skoki, a w lepszej wersji tylko jeden. Coś mam chyba spieprzoną
konfigurację gcc pod linuxem, bo rzeczywiście to powinno się ładnie
zoptymalizować do przesłań warunkowych.
w.
hmm, widze, ze -m32/-m64 robi roznice (1 skok )dla kodu,
ktory wrzucilem. wyglada na babol w gcc-u...
> hmm, widze, ze -m32/-m64 robi roznice (1 skok )dla kodu,
> ktory wrzucilem. wyglada na babol w gcc-u...
>
zglos bug report, a udziele ci bardzo cennej rady(sic!) :)
--
kiedys cos mi sie obilo o uszy (@gcc-mailinglist), ze krotki skok @32
na aktualnych prockach jest szybszy od dluzszego szeregu instrukcji.
czyzby, to bylo to?
nie to nie to, cos co moze sie skonczyc dla ciebie duzo bardziej
bolesnie.
--
Prosto. Taka jest typowa praktyka u�ycia tegotypu konstrukcji.
> Bo jezeli kazda liczba jest rownoprawdopodobna
> to to jest najzadszy przypadek.
Wiesz, najpierw to ta "ka�da liczba" musia�aby by� reprezentowalna w
komputerze.
> Michal wrote:
> > On Wed, 30 Dec 2009 11:19:51 +0100
> > Sebastian Kaliszewski <s.bez...@remove.this.informa.and.that.pl>
> > wrote:
> >
> >
> >> Zapewne dlatego, że najczęstszy przypadek (x zwracany bez zmian)
> > a jak do tego doszedles?
>
> Prosto. Taka jest typowa praktyka użycia tegotypu konstrukcji.
Glupie jakies to wytlumaczenie
>
> Wiesz, najpierw to ta "każda liczba" musiałaby być reprezentowalna w
> komputerze.
Jakbys troche pomyslal i obejrzal sygnaturke funkcji to wiedzialbys,
jaka jest dziedzina funkcji, o ktorej mowimy i nie wypisywal bys glupot.
Jak doro�niesz programistycznie to mo�emy do tej rozmowy wr�ci�.
>
>> Wiesz, najpierw to ta "ka�da liczba" musia�aby by� reprezentowalna w
>> komputerze.
>
> Jakbys troche pomyslal i obejrzal sygnaturke funkcji to wiedzialbys,
> jaka jest dziedzina funkcji, o ktorej mowimy i nie wypisywal bys glupot.
Misiu, co ma sygnaturka do twojej "ka�ej liczby".
zatem j.w.
> Michal wrote:
> > On Thu, 31 Dec 2009 13:56:04 +0100
> > Sebastian Kaliszewski <s.bez...@remove.this.informa.and.that.pl>
> > wrote:
> >
> >> Michal wrote:
> >>> On Wed, 30 Dec 2009 11:19:51 +0100
> >>> Sebastian Kaliszewski <s.bez...@remove.this.informa.and.that.pl>
> >>> wrote:
> >>>
> >>>
> >>>> Zapewne dlatego, że najczęstszy przypadek (x zwracany bez zmian)
> >>> a jak do tego doszedles?
> >> Prosto. Taka jest typowa praktyka użycia tegotypu konstrukcji.
> >
> > Glupie jakies to wytlumaczenie
>
> Jak dorośniesz programistycznie to możemy do tej rozmowy wrócić.
lol, jak nauczysz sie podstaw matematyki to mozesz zaczac bawic sie
BASICiem a pozniej moze nawet jakies skrypty w exelcu.
>
> >
> >> Wiesz, najpierw to ta "każda liczba" musiałaby być reprezentowalna w
> >> komputerze.
> >
> > Jakbys troche pomyslal i obejrzal sygnaturke funkcji to wiedzialbys,
> > jaka jest dziedzina funkcji, o ktorej mowimy i nie wypisywal bys glupot.
>
> Misiu, co ma sygnaturka do twojej "każej liczby".
Jak nauczysz juz sie pisac jakies hello worldy to zainteresuj sie tym
co zwraca funkcja main.
Po prostu ROTFLMAO, kolego bez nazwiska
Widzisz, jakby� mia� jakie� sensowne do�wiadczenie to by� wiedzia�, �e
niezwykle rzadko wykorzystuje si� pe�en zakres danego typu liczbowego, a
zw�aszcza tego najcz�ciej w C/C++ u�ywanego, czyli int.
Po drugie, je�li m�wi�c o r�wnym prawdopodobie�stwie wyst�powania liczb
mia�e� na my�li jakikolwiek ograniczony typ to napisa�e� bzdur� -- dla n
bli�szych ko�ca zakresu typu ni� 0, przy jednostajnym rozk�adzie
przypadek z ostatniego else wcale nie jest najrzadszy
Po trzecie, to sobie poszukaj has�a "Prawo Benforda" (to apropos
znajomo�ci matematyki).
> napisałeś bzdurę -- dla n
> bliższych końca zakresu typu niż 0, przy jednostajnym rozkładzie
> przypadek z ostatniego else wcale nie jest najrzadszy
Pekam wlasnie ze smiechu.
--
--
Pozdrawiam
Michoo
>Po drugie, je¶li mówi±c o równym prawdopodobieństwie występowania liczb
>miałe¶ na my¶li jakikolwiek ograniczony typ to napisałe¶ bzdurę -- dla n
>bliższych końca zakresu typu niż 0, przy jednostajnym rozkładzie
>przypadek z ostatniego else wcale nie jest najrzadszy
Troche nie rozumiem, bo malo po polsku napisane, ale to nie ma akurat
znaczenia. Nie znamy n, i nie znamy testowanej liczby. Oba przypadki
(2 i 3) sa tak samo mozliwe.
milego dnia, hej
Przeczytaj założenia kolegi bez nazwiska, cytuję:
[...]jezeli kazda liczba jest rownoprawdopodobna
to to jest najzadszy przypadek.
Dla przypomnienia "dyskutowany" kawałek kodu:
if (x < 0) return 0;
else if (x > n) return n;
else return x;
n jest ustalone. Niech x jest typu T.
Jeśli n >= std::numeric_limits<T>::max() a ponadto mamy powyższe
założenie kolegi bez nazwiska, to przypadek z ostatniego else nie jest
najrzadszy z oczywistego powodu.
Tu warto jeszcze przypomnieć, że w rzeczywistej rzeczywistości założenie
kolegi bez nazwiska zwykle nie jest spełnione. Jaki jest na prawdę
rozkład x to może wie (a może nie) programista, może też uda się lepiej
wcelować używając profilowania. Jeśli zaś z góry wiadomo, że nie wiadomo
(np. piszemy optymalizujący kompilator który m.in taki kod ma
optymalizować i wiemy że PGO nie ma -- bo go nie robimy, albo piszemy
obsługę dla wyłączonej opcji PGO) to statystycznie lepszym wyjściem niż
zakładanie rozkładu jednostajnego po całym zakresie typu jest
skorzystanie z prawa Benforda.
Oczywiście, kiedy mamy PGO (Profile Guided Optimizations) to lepiej
sięgnąć do danych z profilowania.
pzdr
> Michal pisze:
> > On Thu, 07 Jan 2010 13:46:29 +0100
> > Sebastian Kaliszewski <s.bez...@remove.this.informa.and.that.pl>
> > wrote:
> >
> >> napisałeś bzdurę -- dla n
> >> bliższych końca zakresu typu niż 0, przy jednostajnym rozkładzie
> >> przypadek z ostatniego else wcale nie jest najrzadszy
> >
> > Pekam wlasnie ze smiechu.
> >
> Czy mógłbyś wyjaśnić "dowcip" też tym mniej bystrym grupowiczom? Nie
> rozumiem jaki błąd popełnił Sebastian, a jak wyjaśnisz to może bym się
> czegoś nauczył?
kod
int fun(int x, int n)
{
if (x < 0) return 0;
else if (x > n) return n;
else return x;
}
max(int) to maksymalna liczba jaka moze przyjac int
min(int) = -(max(int) + 1) to minimalna liczba jaka moze przyjac int
count(int) = 2 * max(int) + 1
Liczb nieujemnych jest wiec tyle co ujemnych.
n -- bedzie zwykle mniejsze od max(int) bo inaczej nie miala by ta
funkcja zadnego sensu. Tak, wiec zakladajac rozklad rownomierny
zmiennej x lub Benforda, ktorym bezmyslnie probowal wytlumaczys swoj
blad Sebastian Kaliszewski, pierwszy przypadek jest najczestszy, drugi
lub trzeci zalezy od liczby n.
--
> n -- bedzie zwykle mniejsze od max(int) bo inaczej nie miala by ta
> funkcja zadnego sensu.
Tu ju� sam przyjmujesz jakie� za�o�enia co do dziedziny problemu.
> Tak, wiec zakladajac rozklad rownomierny
> zmiennej x lub Benforda, ktorym bezmyslnie probowal wytlumaczys swoj
> blad Sebastian Kaliszewski, pierwszy przypadek jest najczestszy,
Tak.
> drugi lub trzeci zalezy od liczby n.
Tak,ale na argument Sebastiana:
>> Zapewne dlatego, �e najcz�stszy przypadek (x zwracany bez zmian)
Sam napisa�e�:
> a jak do tego doszedles? Bo jezeli kazda liczba jest rownoprawdopodobna
> to to jest najzadszy przypadek.
Co jest nieuprawione. Najrzadszy przypadek przy rozk�adzie jednostajnym to:
drugi dla n > 0
drugi gdy n > max(int)/2
trzeci gdy n < max(int)/2
Wi�c w sumie dowcipu nadal nie dostrzegam.
--
Pozdrawiam
Michoo
Przeczytaj jeszcze raz co sam napisa�e�... Dla u�atwienia cytuj�:
"Bo jezeli kazda liczba jest rownoprawdopodobna to to jest najzadszy
przypadek."
Jak widzisz, sam (w ko�cu, po blisko dwu tygodniach, brawo!) doszed�e�,
�e to nie jest prawda, nawet przy za�o�eniu �e "ka�da liczba jest
r�wnoprawdopodobna".
Ja napisa�em...
"Zapewne dlatego, �e najcz�stszy przypadek (x zwracany bez zmian)
przechodzi przez dwa warunki a nie jeden. Bez optymalizacji kierowanych
profilowaniem (PGO) kompilator si� raczej nie domy�li, �e co� z drugiego
else jest przypadkiem najcz�stszym. "
I na pytanie sk�d wiem odpisa�em:
"Taka jest typowa praktyka u�ycia tegotypu konstrukcji. "
Otďż˝, dzieciďż˝ drogie, dyskutowana konstrukcja to typowe "nasycenie
arytmetyczne" -- w praktyce tak si� to stosuje by gross wynik�w trafia�a
pomi�dzy kra�ce przedzia�u a nie by�a obcinana. Wyniki obci�te nios�
tylko tak� informacj�, �e s� obci�te -- s� wi�c ma�o ciekawe. Zwykle
sytuacja gdy wi�kszo�� wynik�w jest obcinanna jest sytuacj�
patologiczn�. W niepatologicznym przypadku to w�a�nie zwykle drugi else
jest tym przypadkiem najcz�stszym.
No, ale �eby to wiedzie�, trzeba troch� w �yciu kodu napisa� i jescze
trochďż˝ zobaczyďż˝