PDA

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

pulsar
13/11/2007, 22:27
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.