Tam Sürümünü Görmek İçin : Donguler, ufak bir performans sorusu
sekizbit
04/11/2007, 01:36
Merhaba benim donguler hakkinda merak ettigim ufak bi konu var.
Ornegin
int i, k = 2000;
for(i=0 ; i<k/5 ; k++)
yapilacakis(k);
yukardaki for dongusunde, for cevrimi her yapilmadan once ortadaki kosul saglanip saglanmadigi kontrol ediliyor. peki bu kontrolu yaparken her seferinde k/5 islemini yapiyormu yoksa, ilk seferde yapip sonra o degeri mi kullaniyor ?
benim tahminim her seferinde yapiyordur, cunku icerden k veya diger degiskenler degistirilebilir. Veya belkide bunun icin daha gelismis bir yontem izliyordur ?
Euclides
04/11/2007, 09:28
hayır her seferinde yapmıyor. çünkü k ve diğer değişkenler değişemez. (değişiyor olsayı bunu görürdü :) ) eğer multithreaded bişi yapmak istiyorsan "volatile int" şeklinde tanımlamalısın.
vc++'de ben şöyle birşey görmüştüm.
int k = 0;
for(int i = 0; i < 1000; i++)
k++;
kodunu
k = 1000;
olarak derliyor.
lektroon
05/11/2007, 09:49
Euclides, senin kodundaki dongude k degiskeni artirilmiyor. Bu yuzden de optimizer, o sekilde yorumlamis olabilir. Ancak sekizbit'in kodunda farklilik var. k degiskeni surekli artiriliyor ve o anki degerine gore bir condition olusturuluyor. Bence her seferinde k/5 islemini yapiyordur.
myavuzselim
05/11/2007, 10:10
Sekizbit yanlislikla i++ yerine k++ yazmistir, yoksa dongu k overflow olana kadar bayagi uzun bir sure calisirdi :)
sekizbit
06/11/2007, 01:19
Sekizbit yanlislikla i++ yerine k++ yazmistir, yoksa dongu k overflow olana kadar bayagi uzun bir sure calisirdi :)
evet haklisiniz yanlislikla k++ yazmisim. orasi i++ olacak, ancak ayni durumdayken yinede kosullari olusturan degerler kodun icinden degistirilebilir.
bu durumda her seferinde yeniden hesaplar gibime geliyor benim ?
acehreli
06/11/2007, 02:05
yapilacakis(&k) dersek, ve yapilacakis'in tanimi bu derleme biriminde gorulemiyorsa, derleyici k'nin orada degisip degismedigini bilemeyebilir ve k/5'i her seferinde hesaplamak zorunda kalabilir.
Ama eger yapilacakis'in tanimi bu derleme biriminde tamamen goruluyorsa, derleyici k'nin degismedigini anlayarak k/5'i yalnizca bir kere hesaplayabilir.
Bunlar teori de degil, derleyiciler gercekten bu tUr eniyilestirmeleri yapiyorlar.
Ali
sekizbit
06/11/2007, 06:54
ozaman yazdigimiz yazilimin hizi, derleyicinin kalitesine gorede degisiri yani ?
acehreli
06/11/2007, 20:22
Evet, derleyici programin hizini etkiler.
Ali
sekizbit
07/11/2007, 01:00
Peki hangi derleyicinin hangi ozelliklere sahip oldugunu, yani yazacagim programin hangisinde daha hizli calisacak bicimde derlenecegini okuyabilecegim bi kaynak veye kodumu test edebilecegim bi program vs.. varmi bildiginiz ?
acehreli
07/11/2007, 20:17
"compiler benchmark" gibi aramalar sonuc verebilir. Ornegin gecmisten soyle bir karsilastirma buldum:
http://www.coyotegulch.com/reviews/intel_comp/intel_gcc_bench2.html
Ali
Euclides
09/11/2007, 19:34
Sonunda ubuntuda ida pro kullanmayı becerdim.
test.txt'deki kodu gcc ve vc++ express ile derledim sonuçlar resimlerde
gcc -O3 test.c
ve
cl /O2 /Ot /Og test.c
komutları ile derledim gcc çok iyi bir tahmin yaptı
fakat vc++ bölmeye devam ediyor :(
sekizbit
12/11/2007, 08:25
Ali bey`e verdigi bilgilerden dolayi sayin Euclides`e de yaptigi testden dolayi cok tesekkur ederim.
birde bu ida yazilimi ne ise yariyor ?
Euclides
12/11/2007, 11:46
Bir önceki mesajımdaki screen shot'lar ida'nın. Görüldüğü gibi bir disassembler.
myavuzselim
12/11/2007, 13:18
euclides'in verdigi screenshotta gcc'nin yaptigi optimizasyon cok ilginc. Kodu soyle birsey haline getirmis:
void doSomething(int *h)
{
(*h)--;
}
int main(void)
{
int reg = 2000, k;
while (reg != 1667)
reg--;
k = 1667;
printf("%d",k);
return 0;
}
Isin ilginc tarafi gcc doSomething'in ne yaptigini anlamis ve inline etmis, donguyu iyice kolaylastirmis, k'ya degerini dongu disinda atamis, ama dongunun gereksiz oldugunu farkedememis :)
myavuzselim
12/11/2007, 13:36
Isin baska ilginc yani yukaridaki kodu bir daha derleyince dongu de gidiyor:
$ diff test.s test2.s
1c1
< .file "test.c"
---
> .file "test2.c"
13d12
< movl $2000, %eax
18,22d16
< .p2align 4,,7
< .L2:
< subl $1, %eax
< cmpl $1667, %eax
< jne .L2
sekizbit
12/11/2007, 13:36
dongunun zaman gecirmek gibi bir amacida olabilir ? bu yuzden donguyu yoksaymasi bazen yanlis sonuclara yol acmaz mi ?
Euclides
12/11/2007, 13:47
@myavuzselim:
nasıl derledin ? bir de gcc versiyonu kaç ?
bende uğraştımda loop'dan kurtulmadı bir türlü :)
(gcc'i update mi etsem ne etsem :) )
myavuzselim
12/11/2007, 13:50
Dongunun calisma suresi onemli olsa niye optimize edelim ki? Sonucta optimizasyonu hizlandirmak icin yapmiyor muyuz?
Bak yukaridaki koddaki dongu -O1 ile bile yok oluyor. Demek ki oyle bir dusuncesi yok.
myavuzselim
12/11/2007, 13:55
@myavuzselim:
nasıl derledin ? bir de gcc versiyonu kaç ?
bende uğraştımda loop'dan kurtulmadı bir türlü
(gcc'i update mi etsem ne etsem )
~/Desktop/opt_test$ gcc -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.1.3 --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --enable-checking=release i486-linux-gnu
Thread model: posix
gcc version 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)
~/Desktop/opt_test$ gcc -S -O3 test2.c
Bu arada yanlis anlama olmasin, test2.c senin kod degil, yukarida verdigim kod.
Euclides
12/11/2007, 14:26
hmmm şimdi anladım
acehreli
12/11/2007, 21:23
sekizbit, dongulerin ne kadar zaman alacaklari tanimlanmadigina gore derleyiciler zaman gecirmeye calismayacaklardir. :)
Ali
sekizbit
13/11/2007, 10:10
ya aslinda bakinca mantiksiz gercekten ama buna derleyinin tek basina karar vermesi de cok uc noktalarda bazen sorun cikartabilir. cunku ben hatirliyorum, flashta zaman gecirmek icin dongu kullanmistim bi seferinde :)
Euclides
13/11/2007, 10:30
diyelim ki gerçekten 100us'lik bir geçikmeye ihtiyacımız var ve bunuda böyle yapmak istiyoruz.
Hiç optimizasyon yapmayalım
problem şu: döngünün nasıl derlendiğinin bir kuralı yok ki.
Yani bu döngünün assembly karşılığı onlarca farklı şey olabilir ve hepsininde çalışma süresi farklı olur.(Hatta bazılarının çalışma süresi sabit değil dinamiktir.)
Netice biz 100us'lık geçikmeyi elde edememiş oluruz.
acehreli
13/11/2007, 20:57
Zaman gecirmek icin dongu kullanmanin iki sorunu da var: donguyu calistirdigi icin cpu daha fazla enerji harcar ve cpu baska is icin kullanilamamis olur.
Ali
dolanırken gördüm bu soruyu.. uzun süredir de hiç bir şeye cevap vermiyordum .. zaman geciktirmek için döngü ve cpu ısınması arasındaki mantıksal (Brah!!) cıkarıma nazaran eski dost euclides'in demek istediğini multitreat bir cpu ve farklı machine code lu derlemelerde zamanı döngü ile tutturma imkansızlığıdır.
Forum Yazılımı : vBulletin v3.7.3, Copyright ©2000-2008, Jelsoft Enterprises Ltd.