PCPROG.4

22 Apr 1994 - 05 Jan 1995

Topics

  1. algoritmi (153)
  2. comment (15)
  3. ms.dos (123)
  4. windows (304)
  5. asembler (103)
  6. basic (80)
  7. jezici (196)
  8. pascal (880)
  9. cccc (586)
  10. cpp (157)
  11. clipper (1267)
  12. baze.podataka (525)
  13. razno (529)

Messages - jezici

jezici.104 djelovic, -> #98, bojt
> Ok. A šta se dešava ako radiš sa trodimenzionalnom matricom? Onda > imaš dvodimenzionalni niz pointera (generalno valjda poniterski niz > ima n-1 dimenziju glavnog niza), što može da api pozamašnu količinu > memorije (a kod matrica, zna se, memorije nikad dosta). U slučaju > matrica sa promeljivim dimenzijama to je sasvim ok i omogućava > značajne uštede u memoriji. Medjutim, ako su matrice pune, samo se > džaba arči memorija na poinetrske nizove. žini mi se da jedan pointer po nizu elemenata i nije neki balast, al' ukoliko već hoćeš "napakovane" matrice ima C i to (pročitaj prethodne četri poruke). Lepota C++-a je u tome što dopušta da se zameni čak i mehanizam čuvanja matrice, a da na ostalom kodu ništa mora da se menja. > Praktične uštede u brzini taj pristup bi mogao dati tek u slučaju da se > elementima matrice pristupa sumanuto po nekom random principu. žim postoji > neka zakonitost, dobar optimizator će pristup tekućem elementu svesti tek > na *jedno* sabiranje, to jest na predhodnu adresu dodaće na početku > definisanu konstantu. Isto tako i ja recimo sabiram redove: namestim pointere na odgovarajuće članove i onda opičim jedno *p++ = *q++ u while petlji. Opet, moj pristup ima prednost: tvoja matrica je smeštena cela u jedan HUGE niz, tako da je za dodavanja konstantne adrese potrebno HUGE uvećavanje pointera. Na drugu stranu, kod mene je svaki red alociran odvojeno, tako da je za ono p++ potreno samo LARGE uvećavanje. Naravno, na FLAT memorijskom modelu tih problema nema, i naši pristupi bi trebali da budu približno isto brzi. Što se optimizacije tiče, uz pragmu "no pointer aliasing" bi C/C++ kod trebao da se optimizuje isto toliko dobro koliko i Fortran kod, pod uslovom da su isti ljudi pravili i jedan i drugi kompajler (Microsoft C i Fortran, Watcom C i Fortran, ...). > Nego, kad će bre više ta determinanta? To je samo 15-20 linija > koda... Uz poruku je. Nisam pisao samo funkciju za izračunavanje determinante nego celokupnu klasu Matrix sa sabiranj╩I, mnogąnjem, poređenjem i sl. Sam program MATRIX.EXE očekuje da mu daš veličinu matrice i članove, a onda on izračunava determinantu i govori koliko je to trajalo. Ukoliko matrica može da stane na ekran, on je prvo ispiše. Namerno nisam popunio matricu sa onim 100*cos(...) jer mi je to kada sam pokušavao za velike matrice davalo deljenje nulom. Posle sam testirao tvoj algoritam na nekom Basicu, i ista stvar. Mož' da bidne bug u mom programu, pa ako je to slučaj reci. Anyway, podatke možeš da izgenerišeš sam pa da mu proslediš kroz redirekciju. Najveća matrica koju može da primi je po mojim procenama negde oko 250x250. P.S. Petlju nisam stavio jer tvoj algoritam za matrice uništava originalnu matricu. Deset puta tako, i ko zna šta bi se dobilo? :) matrix.zip
jezici.105 bojt, -> #104, djelovic
>> žini mi se da jedan pointer po nizu elemenata i nije neki >> balast... Sve zavisi od toga koliko memorije imaš i koliko ti može zafaliti... ;) >> tvoja matrica je smeštena cela u jedan HUGE niz, tako da je >> za dodavanja konstantne adrese potrebno HUGE uvećavanje >> pointera. Na drugu stranu, kod mene je svaki red alociran >> odvojeno, tako da je za ono p++ potreno samo LARGE uvećavanje. To stoji, medjutim tu opet ostaješ zakinut za memoriju od kraja poslednjeg reda do kraja segmenta, dok se HUGE niz prostire kroz više segmenata i makimalno koristi raspoložive resurse. Dobitak u brzini koji se dobija "tvojim" načinom adresiranja može za posledicu da ima da neki problem jednostavno ne može da se uradi. Naravno, cela ova priča i nema mnogo smisla za real programe, pošto nema ni dovoljno memorije da bi se u nju smestili "pravi" problemi (oni koji iziskuju jako mnogo vremena za rešavanje). U protected modu, što je prava stvar, nema ni huge ni large ni ostalih zaj*bancija... >> Što se optimizacije tiče, uz pragmu "no pointer aliasing" bi >> C/C++ kod trebao da se optimizuje isto toliko dobro koliko i >> Fortran kod, pod uslovom da su isti ljudi pravili i jedan i >> drugi kompajler (Microsoft C i Fortran, Watcom C i Fortran, ...). Moguće da je u fortran ugradjen dobar deo C-optimizacije nižeg nivoa, ali teško mogu da poverujem da to važi i u obrnutom smeru. >> Namerno nisam popunio matricu sa onim 100*cos(...) jer mi je >> to kada sam pokušavao za velike matrice davalo deljenje nulom. Hm, delenje sa nulom nebi smelo da ti da, ali samu determinantu može da ti da kao 0, pošto je determinanta matrice sa velikim elementima najčešće mali broj. Za jako velike matrice determinanta je jako jako mali broj, pa kod množenja sa tekućim elementom glavne dijagonale ona krene ona počinje da poprima eksponent E-5, E-10, E-50, E-200, itd, sve dok je u jednom trenutku kompajler ne proglasi za 0. Sa druge strane, ako su elementi matrice mali, determinanta poprima sve veću i veću vrednost, sve dok ne prijavi neki overflow. To bi moglo da se izbegne tako što bi se u glavnoj petlji oduzimao eksponent od trenutne vrednosti determinante (tako da ostane samo mantisa) i dodavao nekoj integer varijabli, pa na kraju posla ispisati krajnju mantisu determinate i nalepiti taj integer kao eksponent. ;) Generalno, kod velikih matrica od determinante nema mnogo koristi, zato što je najčešće to jako jako jako veliki ili mali broj. Mnogo bi bilo bolje da smo odmah krenuli na neki problem koji ima više smisla, na primer na rešavanje sistema linearnih jednačina, al' tu bi bilo nešto više posla. Ajd sad da probamo... ;)
jezici.106 bojt, -> #104, djelovic
Hm, nešto ne štima kod ovog MATRIX-a, tj za one matrice za koje se pouzdano zna kolika je determinanta daje nešto bez veze. Anyway, ja sam propuštao matricu 200x200, čisto da vidim odnos vremena. Elemente matrice sam generisao na sledeći način (opet malo tarzan basic-a): input n1 n=n1-1 dim double a(n,n),coef(9),z for i=0 to 9 read coef(i) next k=0 z=1 for i=0 to n for j=i to n a(j,i)=z*coef(k) a(i,j)=a(j,i) k=k+1 z=-z if(k=10) let k=0 next next data 1.4,1.2,1.1,1.5,1.25,1.13,1.32,1.18,1.27,1.36 Tako definisanu matricu sam ubacio u fajl i punio MATRIX njime preko redirekcije. E sad, za red matrice 200 determinanta bi morala da bude 237539.5, dok je MATRIX prijavio -2.52725E+21 (neki put i nešto drugo, neki put neće da radi uopšte). Što se tiče brzine, kod mene je (486DX2/66 VLB) MATRIX takvu matricu radio u proseku za oko 3.6 sekundi, dok je program u fortranu dobijen pomoću Microsoft Fortran-a 5.00 (command line FL -AH -Gs -G2 -4I2 det.for) istu tu matricu radio za oko 2.8 sekunde, a i davao je dobre rezultate ;). Isti program kompajliran Microway NDP 486 Fortran-om v4.0.2 radio je 1.3 sekunde (uz isti rezultat). Uz poruku kačim zip sa DET.FOR i DET.EXE, a DET486.EXE je prevelik (zbog DOS exteneder-a), pa njega neki drugi put. P.S. Šam-Pi-Oni! ;) det.zip
jezici.107 afilipovic, -> #102, djelovic
>> S obzirom da je moja tvrdnja pogresna, onda je i ovo >> gore. Za matrice cije su dimenzije poznate za vreme >> komapajliranja, matrica se *ne* definise kao niz pointera >> na nizove. Pogresno sam citirao tvoju poruku tako da stvarno ispade da se slazem sa tobom i ako posle u tekstu pokazujem da je to sto si tvrdio pogresno ali posto sam to primetio tek posto sam poslao exec bio sam previse umoran da ga brisem i ispravljam i saljem ponovo ;)). Ali vidim da smo se konacno slozili oko toga da matrica sa konstantnim dimenzijama nije isto sto i niz pointera na nizove. Pozdrav, Nenad
jezici.108 afilipovic, -> #103, djelovic
>> Ovde vec nisi u pravu :). Za matricu cije dimenzije nisu >> poznate za vreme kompajliranja, operator [][] je potpuno >> neupotrebljiv - za Pa to sam i rekao, pretpostavimo da moze [][] i pokazao ti da kompajler prijavi gresku. Daklem takva konstrukcija je neupotrebljiva za dinamicke nizove. >> moraju da budu poznati za vreme kompilacije. Zato je >> *jedini* nacin da se definise dinamicka matrica preko >> niza pointera na pointere, sto onda za pristup clanovima >> daje moju formulu. To je samo jedan od dva moguca nacina drugi nacin je onaj preko koga sam ja implementirao matricu dakle kao vektor cijim clanovima pristupas preko i*n+j. E sada ovde imas ustedu u memoriji jer nema dodatnog niza pointera ali je po svemu sudeci pristup sporiji (koliko to treba videti). Drugi ozbiljniji nedostatak se javlja pod DOS - em jer ne mozes onda imati niz veci od 64K doduse takav problem se javlja i kod tebe ali tek kada ti jedna dimenzija matrice ( dal pointerskog niza ili vektora na koji pokazuju ti pointeri ) postane veca od 64K. Pozdrav, Nenad .P.S. Nema sta prilicno konstruktivna diskusija ajd da vidimo i konkretne rezultate merenja FORTRAN spram C++ - a.
jezici.109 afilipovic, -> #106, bojt
>> fortranu dobijen pomocu Microsoft Fortran-a 5.00 (command >> line FL -AH -Gs -G2 -4I2 det.for) istu tu matricu radio >> za oko 2.8 sekunde, a i davao je dobre rezultate ;). Hmmm plasim se da ovo nije korektno merenje. Da bi sve bilo po propisu :) prvo treba djelovic da ispravi program kako bi se dobijali tacni rezultati a onda da se kompajlira i *.for i *.cpp program tako da daje isti kod dakle 386+387 ili nesto drugo sto se dogovorite. >> Uz poruku kacim zip sa DET.FOR i DET.EXE, a DET486.EXE je >> prevelik (zbog DOS exteneder-a), pa njega neki drugi put. Da ali ako bi se C++ poterao tako da vidi ravnu memoriju mozda bi rezultati bili isti. Pozdrav, Nenad
jezici.110 maksa, -> #109, afilipovic
>> Da ali ako bi se C++ poterao tako da vidi ravnu memoriju mozda >> bi rezultati bili isti. MS FORTRAN ne vidi ravnu memoriju.
jezici.111 spantic, -> #106, bojt
> P.S. Šam-Pi-Oni! ;) FORTRAN, FORTRAN :)
jezici.112 asterix, -> #111, spantic
>> P.S. Šam-Pi-Oni! ;) > > FORTRAN, FORTRAN :) A ovo se ne važi, ti imaš i navijače...
jezici.113 dcolak, -> #111, spantic
│> P.S. Šam-Pi-Oni! ;) │ │ FOR-TRAN, FOR-TRAN :) Polako, polako :)) Dajte prvo da taj C++ program _proradi_ :))) Pa onda da vidimo ;) Sledge DAMMIR!
jezici.114 maksa, -> #113, dcolak
>> Dajte prvo da taj C++ program _proradi_ :))) I da se prevede i nekim pristojnim prevodiocem. ;) PS 'OĆE-MO RE-VANŠ ;)
jezici.115 dejanr,
Borland je izdao C++ 4.0 update i PowerPack for DOS koji uključuje 16 i 32-bitni DOS extender, Turbo Vision 2.0 i novu 32-bitnu verziju Borland Graphics Interface-a (BGI). Uključene su i runtime licence za rezultujuće aplikacije. NOVOSTI/microb 4.677 i NOVOSTI/microb 4.690.
jezici.116 mdave, -> #114, maksa
■> I da se prevede i nekim pristojnim prevodiocem. ;) TS Modula-2 ? ;>
jezici.117 maksa, -> #116, mdave
>> > I da se prevede i nekim pristojnim prevodiocem. ;) >> >> TS Modula-2 ? ;> Što da ne ? Jednom je neko predložio da se napravi uporedni test, tako što bi se neki poslić uradio na svim jezicima u upotrebi. Možda bi bilo dobro, i u duhu ove informativne i konstruktivne rasprave, da neko odradi celu ovu priču sa determinantama i na Moduli. PS Tipujem da bi ti rezultat izbrisao taj zlobni smajli. ;)
jezici.118 kale, -> #106, bojt
Uzeo sam onaj .for i napravio od njega .c. Program mi je za n=200 dao Det=237539.49993801536000 C+Unix (moj) 4.1? DET=237539.49993810620000 FORTRAN+DOS (tvoj) 5.65 DET=237539.49993810620000 FORTRAN+DOS(pod Unix-om) (tvoj) 6.21 C je koristio 8 bajtne real-ove. Da nije FORTRAN koristio 10? Tvoj neće da radi za n>256. Moj radi dok ima memorije (ili swap-a). Pored vremena je ? jer vreme grozno varira. žim se računar (486DX/33, jedna banka RAM od 16 MB) podigne bilo je i samo 3.5, međutim, posle se to kvari da bi se ustalilo (čuj ustalilo, nikad se ne ustali!) na između 3.95 i 4.30. Da stvar bude još luđa, jedna stara verzija (det.ok) mi evo sada stalno daje 0.10 sec bolji rezultat od ove koju sam sada kompajlirao, a cela razlika im je u datumu kreiranja! Ako ih pustim više istovremeno (probao sa 5) vreme se malo poveća, oko 0.2 sec po komadu. Đavo mi nije dao mira pa sam pogledao kako izgleda napravljeni kod. Moram priznati da sam očekivao mnogo bolji. Pravi biser je način na koji kompajlerov optimizovani kod računa vrednost funkcije "fabs". Poziva funkciju pri čemu, naravno prvo gurne double float na stek. Ta funkcija prvo sačuva EBP na steku, pa zatim svoje argumente sa steka stavi (ponovo!) na stek pa pozove rutinu koja tu vrednost sa steka učita u koprocesor (jedna koprecesorska naredba) i izvrši naredbu FABS (druga koprocesorska naredba). Rezultat pozivajućim programima ostaje u registru ST i glavni program ladno dalje radi sa koprocesorom, što znači da je kompajler računao na njega pri kompilaciji. Evo i izgleda one najdublje petlje (3 nivo): Ovo je napravio glupi optimizer, mov eax, DWORD PTR [ebp-20] add eax, ebx fld QWORD PTR [edi+eax*8] fmul QWORD PTR [ebp-16] mov eax, DWORD PTR [ebp-24] add eax, ebx fadd QWORD PTR [edi+eax*8] fstp QWORD PTR [edi+eax*8] fwait add ebx, ecx dec esi jne SHORT $L20003 a ovo ja: add edi, ebx fld QWORD PTR [esi+edi] fmul st,st(1) fadd QWORD PTR [edi] fstp QWORD PTR [edi] loop short $FC340 Razlika u vremenu izvršavanja je minimalna - 0.3 - 0.4 sekunde, što će reći ni 10%. Izgleda da jedno množenje i jedno sabiranje real-ova pojedu toliko vremena da broj pristupa memoriji i integerska sabiranja ne mogu tu ništa značajno da promene. Razlika bi sigurno bila značajnija na 486DX2 ili 486DX4. Još nešto: tvoj program drži istu brzinu bez obzira na broj elemenata (posledica FORTRAN-ovog redosleda elemenata matrice u memoriji koja je drugačija nego u C-u), dok je C verzija brža do 256 elemenata, a zatim brzina pada za jedno 70% (očigledno mi tada stalno trash-ira cash). I još nešto: .exe koji si poslao radi samo do 256 elemenata, ova radi dok ima memorije (uključujući swap). N=1000 det=-926,518,739,657,204,560,000. 733.72 sec Pozdrav, Kale
jezici.120 bojt, -> #118, kale
>> Det=237539.49993801536000 C+Unix (moj) 4.1? >> DET=237539.49993810620000 FORTRAN+DOS (tvoj) 5.65 >> DET=237539.49993810620000 FORTRAN+DOS(pod Unix-om) (tvoj) 6.21 >> C je koristio 8 bajtne real-ove. Da nije FORTRAN koristio >> 10? Tvoj neće da radi za n>256. Moj radi dok ima memorije >> (ili swap-a). Ne može više od nekog n>2xx, pošto je to program u realnom modu i granica mu je slobodna memorija u okviru osnovnih 640K. 256*256*8=512K, taman za kod i matricu. Kod tebe se namestilo baš na 256, što deluje kao neko sistemsko ograničenje dimenzija, ali nije, samo je memorija u pitanju. ;). Probaj da uradiš EXEHDR /MAX:0x00BA DET.EXE (EXEHDR ide uz svaki MS compiler) čime se "Extra paragraphs wanted" smanjuje sa 64K na 0xBA pa će biti memorije i za matrice preko 256. Što se brzine tiče, ti si koristio Unix C kompajler koji radi u 32-bit protected modu, pa je i logično da može da uradi više, kao i da radi brže od mog programa koji radi u realnom modu (linearno vidi svu memoriju, ne pati se sa segmentima itd). >> Pored vremena je ? jer vreme grozno varira. Kao što sam na početku cele ove priče rekao, matrice manjih dimenzija (pa i reda 200) se toliko brzo proračunavaju da se vreme računanja ne može precizno odrediti, pa sam predlagao da "prava" trka padne medju 386 komapjlerima na matricama većeg reda, kada proračun traje po nekoliko minuta. Pandan tvom C programu koji radi pod Unix-om bio bi program dobijen odgovrajućim 386 Fortran komapjlerom. Ovako odokativno, s obzirom da je kod tebe (486/33) moj program radio 5.65 sekundi, što je približno 2 x 2.8 sekundi koliko je radio kod mene (486/66). Mejdutim, program koji sam dobio koristeći Microway NDP 486 Fortran (ovaj koji sam okačio na sezam je dobijen MS Fortranom koji radi u realnom modu, tj daje kod koji može da trči i na XT-u) radio je 1.27 sekunde, tako da bi se kod tebe izršavao približno 2.54 sekunde, što je znatno manje od 4.1 koje si dobio sa Unix C-om (61%) ;). >> Ovo je napravio glupi optimizer... >> a ovo ja... >> Razlika u vremenu izvršavanja je minimalna - 0.3 - 0.4 >> sekunde, što će reći ni 10%. Izgleda da jedno množenje i >> jedno sabiranje real-ova pojedu toliko vremena da broj >> pristupa memoriji i integerska sabiranja ne mogu tu ništa >> značajno da promene. Razlika bi sigurno bila značajnija na >> 486DX2 ili 486DX4. Hm, ako bi se slična optimizacija (koju si ti ručno uradio) prenela na sve tri petlje dobilo bi se još ponešto, mada, kao što sam već rekao, pretpostavljam da odgovor leži u tome što bibliotečke funkcije koje korespondiraju sa koprocesorom u slučaju fortrana imaju mnogo manje provera, jer do mnogih nepredvidjenih situacija u fortranu kao višem programskom jeziku jednostavno ne može da dodje. >> N=1000 >> det=-926,518,739,657,204,560,000. >> 733.72 sec Kod mene je za N=1000 (MicroWay NDP FORTRAN 486 V4.0.2 + Ergo DOS Extender): DET=-9.2651873966273874E+20 234.53sec Recimo da kod tebe radi 2x sporije to bi bilo 234.53x2=469.06sec, što bi bilo 56% brže nego C program pod UNIX-om. Ne bi bilo loše da nabaviš neki Fortran za taj Unix pa da probaš tako (jedino što možda neće raditi ALLOCATE ako je dinamička alokacija kod tog fortrana drugačije rešena - onda statički dimenzioniši REAL*8 a(0:999,0:999) ). Što se tiče DET u protected modu, program su malo velik da bi se slao preko modema u EXE formi (234K), jer se u njih ugradjuje i DOS EXTENDER. Ako imaš neki DOS EXTENDER, npr Phar Lap RUN386 ili Ergo DOS Extender, onda bih poslao EXP ili LTL. Ako neko insistira, može i EXE. ;)
jezici.121 bojt, -> #118, kale
Uostalom, evo ga DETX.EXE koji radi u protected modu, zipovano 111K. detx.zip
jezici.122 mdave, -> #117, maksa
■> Možda bi bilo dobro, i u duhu ove informativne i konstruktivne ■> rasprave, da neko odradi celu ovu priču sa determinantama i na ■> Moduli. A tvoj pulen je... ? ;) < pobegoh sa PMF-a zbog determinanti, a sad... ;( >
jezici.123 zolika, -> #117, maksa
>> Možda bi bilo dobro, i u duhu ove informativne i konstruktivne >> rasprave, da neko odradi celu ovu priču sa determinantama i na >> Moduli. >> >> PS Tipujem da bi ti rezultat izbrisao taj zlobni smajli. ;) More, dajte ovamo te sorsove, da ih prevedem i uteram u TopSpeed kompajler, pa da ti jednom za svagda pokažem da si pogrešno tipovao :-)))))
jezici.124 kale, -> #120, bojt
>> Što se brzine tiče, ti si koristio Unix C kompajler koji radi u >> 32-bit protected modu, ... --------- Samo u 386 modu, valjda. Šteta što bolje ne poznajem 386, 486 - ne znam ni koliko otprilike traju pojedine instrukcije, ni koliko traju pojedini načini adresiranja, a još manje kako se uzajamno kombinuju pojedine instrukcije i načini adresiranja (recimo, udeneš instrukciju između 2 druge i vreme izvršava- nja celog niza ostane nepromenjeno...). Ne znam da li 386 (486) može da radi u 386 modu direktno sa fizičkim adresama. Ko zna? Ako može, sigurno da taj DOS extender to koristi. Ovaj moj radi samo sa virtuelnim adresama, a ne znam da li ga to košta brzine, i ako da - koliko. To bi mogao da bude jedan od razloga za lošije rezultate ovog moga. Drugi deo sam otkrio vrlo brzo pošto si ti poslao svoje rezultate za ovaj sa extended radom. Rezultati su bili previše dobri pa sam posumnjao... Elem, jedno #define a(i,j) a[n1*j+i] umesto #define a(i,j) a[n1*i+j] su ubrzali program na oko 3.6 (umesto 4.1). Asemblerska varijanta one najdublje petlje je smanjila vreme na 3.1. U prošloj poruci sam omašio kad sam rekao da organizacija matrice (tačnije - način na koji je program napisan) ne štima FORTRAN-u, bilo je upravo obrnuto. >> ..., pretpostavljam da odgovor leži u tome što bibliotečke funkcije koje >> korespondiraju sa koprocesorom u slučaju fortrana imaju mnogo manje >> provera, jer do mnogih nepredvidjenih situacija u fortranu kao višem >> programskom jeziku jednostavno ne može da dodje. Za ovaj program nema potrebe za zvanje biblioteka tokom računanja same determinante (ono zvanje fabs je čista glupost - nema potrebe za njime, pa i tamo nema provera - samo arčenje instrukcija). Stack i indeksi se uopšte ne proveravaju u samom programu, ako omaneš bude "memory fault - core dumped", ali se to otkriva preko sistema virtuelne memorije. >> Kod mene je za N=1000 (MicroWay NDP FORTRAN 486 V4.0.2 + Ergo >> DOS Extender): >> DET=-9.2651873966273874E+20 >> 234.53sec >> Recimo da kod tebe radi 2x sporije to bi bilo >> 234.53x2=469.06sec, što bi bilo 56% brže nego C program pod >> UNIX-om. Kod mene je taj radio 444.23. Za isto N (1000) C verzija normalno radi 563, C verzija sa ručno doteranom unutrašnjom petljom 509 (neposredno po podizanju računara mi malopre dade 480.56). To mu dođe 27 odsto prednosti kombinacije DOS+FORTRAN u odnosu na ovaj C i Unix (možda 20 neposredno po podizanju računara). Za mene ostaje najzanimljivije pitanje: da li, odnosno koliko Unix okolina utiče na brzinu? I da ponovim ono sa početka - da li košta preslikavanje virtuelnih u fizičke adrese? Datum na kompajleru (i delovima) je 07.08.90. Uz poruku je C sors, pa ko ima neku svežu verziju, recimo ODT 3.0 ili tako nešto ili Visual C može da ga proba u toj okolini. >> Ne bi bilo loše da nabaviš neki Fortran za taj Unix pa da probaš tako Ne bi bilo loše, samo ne znam gde raste... ;) Pozdrav, Kale ps Stvarno me je iznenadio 486DX2/66. Očekivao sam 70-80% ubrzanja na intenzivnim numeričkim poslovima, a ovo ispade skoro 95%! pps Pretpostavljam da uz taj FORTRAN ide i neki dibager; je li ti problem da ovde ostaviš izgled one najunutrašnjije petlje? 3ps Možda bi ručna optimizacija svih 5 petlji dostigla i prestigla FORTRAN, ali nije bila ideja da testiramo mene... :) det.c
jezici.125 bojt, -> #124, kale
Pustio sam tvoj det.c na Watcom C-u (pod PharLap DOS Extender-om), pa sam probao sa obe definicije a(i,j), jer mi je nekako bilo čudno da radi brže sa a[n1*j+i], pošto se u glavnoj petlji menja samo j. Medjutim, i kod Watcom C-om je bilo brže sa a[n1*j+i] nego sa a[n1*i+j]. Evo i rezultata: WATCOM C 386 V9.01 sa #define a(i,j) a[n1*j+i] N=1000 Det=-926518739646749184000.00000000000000 411.61 sec WATCOM C 386 V9.01 sa #define a(i,j) a[n1*i+j] N=1000 Det=-926518739646749184000.00000000000000 457.97 sec MicroWay NDP 486 Fortran V4.0.2 N=1000 DET= -9.2651873966273874E+20 224.7000 sec >> Pretpostavljam da uz taj FORTRAN ide i neki dibager; je li ti >> problem da ovde ostaviš izgled one najunutrašnjije petlje? Ovaj fortran ima direktnu mogućnost generisanja ASM listinga OBJ-a, pa evo glavne petlje, gde mi je odmah palo za oko da u njoj radi 4 iteracije (odjednom? paralelno?): L109: fld qword ptr ds:L420 ; 00000502 fmul qword ptr [ebx] ; 00000508 fadd qword ptr [eax] ; 0000050a fst qword ptr [eax] ; 0000050c fstp st(0) ; 0000050e fld qword ptr ds:L420 ; 00000510 fmul qword ptr [ebx]+8 ; 00000516 fadd qword ptr [eax]+8 ; 00000519 fst qword ptr [eax]+8 ; 0000051c fstp st(0) ; 0000051f fld qword ptr ds:L420 ; 00000521 fmul qword ptr [ebx]+16 ; 00000527 fadd qword ptr [eax]+16 ; 0000052a fst qword ptr [eax]+16 ; 0000052d fstp st(0) ; 00000530 fld qword ptr ds:L420 ; 00000532 fmul qword ptr [ebx]+24 ; 00000538 fadd qword ptr [eax]+24 ; 0000053b fst qword ptr [eax]+24 ; 0000053e fstp st(0) ; 00000541 add ebx,32 ; 00000543 add eax,32 ; 00000546 dec ecx ; 0000054b jne L109 short ; 0000054c
jezici.126 kale, -> #125, bojt
>> WATCOM C 386 V9.01 sa #define a(i,j) a[n1*j+i] >> 411.61 sec >> MicroWay NDP 486 Fortran V4.0.2 >> 224.7000 sec Taj C baš ne žuri... ;) >> Ovaj fortran ima direktnu mogućnost generisanja ASM listinga OBJ-a, >> pa evo glavne petlje, gde mi je odmah palo za oko da u njoj >> radi 4 iteracije (odjednom? paralelno?): Ne mere paralelno kad svaka instrukcija radi sa vrhom steka. Ako nemaš pametnija posla, zameni fst qword ptr [eax] sa fstp qword ptr [eax] fstp st(0) jer to radi to isto, a jedna instrukcija manje. Takođe, možeš učitavanje promenljive d u koprocesor da izbaciš ispred petlje, pa da u petlji množiš sa st(1) umesto iz memorije (uštediš 300 000 000 učitavanja d). Onda bi petlja izgledala ovako: fld qword ptr ds:L420 ... ... ... jmp nesto L109: fld qword ptr [ebx] mul st, st(1) fadd qword ptr [eax] fstp qword ptr [eax] ... fld qword ptr [ebx]+24 fmul st, st(1) fadd qword ptr [eax]+24 fstp qword ptr [eax]+24 add ebx,32 add eax,32 dec ecx jne L109 short fstp st(0) ; ne zaboravi ovo iza petlje Ako ovo budeš probao, obrati pažnju na uskakanje u petlju (u ovakvu petlju se ulazi odozgo jednom u 4 puta, ostalo je uskakanje). One izmene su skratile petlju za 3 bajta * 4 ponavljanja (ako se ne varam), pa treba promeniti računanje adresa za uskakanje. Ja sam razmotao svoju petlju, i dobio neku uštedu, mada ne spektakularnu. Pretpostavljam da je ostatak razlike u ostalim petljama (i genijalnom fabs!). Kad pređem na ODT 3.0 (ovo je ODT 1.1), javiću ima li kakve promene. Možda bi vredelo probati i sa GNU C++ za Unix. Pozdrav, Kale
jezici.127 bojt, -> #126, kale
>> Ako ovo budeš probao, obrati pažnju na uskakanje u petlju (u >> ovakvu petlju se ulazi odozgo jednom u 4 puta, ostalo je >> uskakanje). One izmene su skratile petlju za 3 bajta * 4 >> ponavljanja (ako se ne varam), pa treba promeniti računanje >> adresa za uskakanje. Pogledao sam posle ceo listing i nema nikakvog uskakanja u petlju, već se prvo vrti za max.broj iteracija deljiv sa 4, pa posle ima isto to za resto iteracija do kraja (3,2,1, ili 0). Zamenio sam L109: fld qword ptr ds:L420 fmul qword ptr [ebx] fadd qword ptr [eax] fst qword ptr [eax] fstp st(0) ... jne L109 short sa fld qword ptr ds:L420 fstp st(1) L109: fld qword ptr [ebx] fmul st, st(1) fadd qword ptr [eax] fstp qword ptr [eax] ... jne L109 short i program se tako mizerno ubrzao da sam se silno razočarao: za N=1000 program koji napravi kompajler je radio 223.90 sec (uključio sam mu neke optimizacije koje ranije nisam uključivao), a sa ovom ručnom intervencijom vreme se poboljšalo na famoznih 222.45 sec, što je ubrzanje od 0.65%. ;( Izgleda da 300.000.000 "fld"-ova iz memorije ne usporava mnogo, s obzirom da tih 8 bajtova najverovatnije drži u kešu. Mada, 0.65% po 0.65%... 1.3% ;) Nego, nešto se mislim, koliko bi se ubrzala stvar da radi 8, 16, 32... iteracija u jednom prolazu kroz glavnu petlju? Jest da bi kod bio duži (recimo da sve ostane u domenu short jmp-a), ali koj zna ;)
jezici.128 bojt,
Pošto me je kale napalio sa ovim mašincem, probao sam da celu rutinu za izračunavanje determinante uradim u asembleru, kako bih video koliko uopšte stvar može da se ubrza. Trudio sam se da maksimalno iskoristim registre procesora i koprocesora, kao i da program napravim tako da, u zavisnosti od mog umeća, bude što je moguće brži. Naravno, prvobitna verzija mašinske rutine, bez obzira na to što je, po mom sudu, ta rutina kao celina u programerskom smislu bila kvalitetnija od rutine koju je napravio kompajler, radila je sporije od fortrana ;), zato što nisam obratio pažnju na to da jmp instrukcije skaču na parne adrese. Posle štelovanja na parne adrese program se nešto ubrzao, ali je i dalje bio sporiji od fortrana: 233.26 sekundi prema 223.94 koje je davao čist fortran-ov program, ili 222.45 koji je davao program u kome je ručno optimizovana samo glavna petlja. Ovo je pre svega zato što u mojoj rutini nije pakovano više iteracija u petlju. Naime, fortran optimizator petlju for i=1 to n a(i)=a(i)+b(i)*c next pretvara u (otprilike) for i=1 to n/4 a(i)=a(i)+b(i)*c a(i+1)=a(i+1)+b(i+1)*c a(i+2)=a(i+2)+b(i+2)*c a(i+3)=a(i+3)+b(i+3)*c next for i=n-n/4*4 to n a(i)=a(i)+b(i)*c next Pošto mi djavo nije dao mira, i ja sam taj isti princip ugradio u moju rutinu, s tim da nisam pravio drugu (kraću) petlju već sam uskako u prvu, u zavisnosti od ostatka n-n/4*4. Pošto mi djavo i dalje nije dao mira napravio verzije ne samo sa 4 već i sa po 8 i 16 iteracija u okviru glavne petlje. Evo i rezutlata koje sam dobio, a za svaku varijantu postoji odgovarajući ASM fajl u arhivi koja je zakačena uz ovu poruku, kao i fortran source: DETORGF.ASM originalna fortran rutina 223.94 sec DETMODF.ASM modifikovana samo glavna petlja DETORGF 222.45 +0.67% DETI1.ASM moja rutina, 1 iteracija u okviru petlje 233.26 -4.16% DETI4.ASM moja rutina, 4 iteracije u okviru petlje 215.31 +4.00% DETI8.ASM moja rutina, 8 iteracija u okviru petlje 213.99 +4.65% DETI16.ASM moja rutina, 16 iteracija u okviru petlje 213.17 +5.05% Sve u svemu, džaba trud... detasm.zip
jezici.129 zzivotic,
[C:\TEST]det Red matrice: 200 DET= 237539.499938106200000 3.129883sec <<<<<<<<<<<<---------------- [C:\TEST]cl -AH -Oxz cdet.c Microsoft (R) C/C++ Optimizing Compiler Version 8.00 .... .... [C:\TEST]cdet Red matrice: 200 Det=237539.49993810620000 2.970000 sec <<<<<<<<<<<<---------------- Šam-pi-oni, šam-pi-oni! Pozdrav, zz ;) cdet.zip
jezici.130 neman, -> #129, zzivotic
> 2.970000 sec <<<<<<<<<<<<---------------- > > Sam-pi-oni, sam-pi-oni! A jel si to uradio pomocu editora ;>
jezici.131 bojt, -> #129, zzivotic
>> Šam-pi-oni, šam-pi-oni! Znao sam da nećeš moći da odoliš. ;) Ajd čik za 386 ;))
jezici.132 bojt, -> #129, zzivotic
Length Method Size Ratio Date Time CRC-32 Attr Name ------ ------ ----- ----- ---- ---- -------- ---- ---- 33428 DeflatN 21766 35% 07-03-94 02:41 d110f87d --w- CDET.EXE ***** Length Method Size Ratio Date Time CRC-32 Attr Name ------ ------ ----- ----- ---- ---- -------- ---- ---- 1967 DeflatX 749 62% 06-24-94 18:54 5511a36f --w- DET.FOR 25616 DeflatX 17239 33% 06-24-94 18:19 f7d04041 --w- DET.EXE ***** C c c, šta je MSC8.00 sve stavio u taj CDET.EXE ;) Šalu na stranu, očigledno da MSC/C++ 8.00, koji je dosta noviji od MSF 5.00 (taj je iz 1988), ima bolji optimizator. ;) Nego, kad ćeš da uzmeš WC90 pa da vidimo kako stoji stvar za N=1000 ? ;)
jezici.133 dcolak, -> #129, zzivotic
│ Red matrice: 200 │ │ Det=237539.49993810620000 │ 2.970000 sec <<<<<<<<<<<<---------------- A koliko je za 1000? Koliko je njima trebalo za 200? :) Ceee Šaaaaaampiooooooooooooniiiiiiiiiiiiiiii :)) Sledge DAMMIR!
jezici.134 bojt, -> #129, zzivotic
D:\DET>CDET Red matrice: 200 Det=237539.49993810620000 2.810000 sec <------------------------ FL -AH -Ox -G2 -4I2 FDET.FOR D:\DET>FDET Red matrice: 200 DET= 237539.499938106200000 2.740000sec <------------------------ har har har ;) E, a pošto C zapravo radi sa jednodimenzionalnim nizom, evo kako to izgleda u fortranu: D:\DET>FDET1 Red matrice: 200 DET= 237539.499937654800000 1.870000sec <------------------------ Ale ale ;) fdet.zip
jezici.135 bojt, -> #129, zzivotic
E da, za N=255 D:\DET>FDET Red matrice: 255 DET=-7234723.915079122000000 6.370000sec D:\DET>CDET Red matrice: 255 Det=-7234723.91507912200000 6.430000 sec Medjutim, za n=256 D:\DET>FDET Red matrice: 256 DET= -474693.399107983400000 6.980000sec D:\DET>CDET Red matrice: 256 cvrc, zaglavi se... dok za n=257 D:\DET>FDET Red matrice: 257 DET= -212.822339428023800 7.080000sec D:\DET>CDET Red matrice: 257 Det=-946561231954731600000000.00000000000000 0.000000 sec tj odma izleti. C c c zz, koristio si unsigned char za brojače... ;)))
jezici.136 zzivotic, -> #132, bojt
>> C c c, šta je MSC8.00 sve stavio u taj CDET.EXE ;) Nisam pratio pažljivo celu diskusiju pa ne znam koji su sve uslovi postojali - da bude što brži i što manji ili samo što brži ili.. C je nagurao 33428 bajtova zato što je stvar kompajlirana sa emulator bibliotekom - da je bilo samo inline za koprocesor bili bi sigurno znatno manje (a možda i malo brže, a? ;). Inače, nisam proveravao šta će se desiti sa dimenzijama niza, memorijom itd. Nisam koristio unsigned char brojače - taman posla, to bi trajalo duže ;) Shvatio sam da treba prosto proveriti koliko koji optimizator dobro radi bez zalaženja u sve ostale detalje. Što se tiče jednodimenzionalnog niza koji pominješ u jednoj od sledećih poruka - nebitno je što C koristi jednodimenzionalni niz - čim napišeš a[i*n + j] uradio si zapravo isto što se dešava (samo interno) kada koristiš dvodimenzionalni niz. Pozdrav, zz
jezici.137 bojt,
Kod ovih DET-ova u realnom modu, kada se FDET izlinkuje sa LINK-om v5.5 iz MSC-a 8.00 (thanks to zz ;) ), isti ne nešto ubrza: CDET N=255 Det=-7234723.91507912200000 6.430000 sec FDET stari N=255 DET=-7234723.915079122000000 6.370000 sec FDET8 novi N=255 DET=-7234723.915079122000000 6.200000 sec Max matricu koju sam mogao da izvučem u 640K je za N=270, a evo još nekoliko rezultata za različito N: FDET8 N=257 DET= -212.822339428023800 6.870000 sec FDET8 N=265 DET= 1.011656687910909E+007 6.980000 sec FDET8 N=270 DET= 1322982.042406064000000 7.080000 sec [ Waiting for Shatobiran... ;) ] fdet8.zip
jezici.139 bojt,
Pošto je zz, samo što je dotakao Watcom C, otkrio kako se uključuje optimizacija ;), Watcom C se opasno približio MicroWay NDP Fortranu, tako da su najnoviji rezultati u natjecatenju C .vs. Fortran su (kod mene) za sada ;) sledeći: Protected mode, N=1000 227.72 sec - Watcom C V9.01 /ox /7 /4s /4r 223.94 sec - MicroWay NDP Fortran V4.0.2 213.17 sec - ručno pisana ASM rutina sa 16 linearnih iteracija Svašta još može da se desi... ;)
jezici.140 de.pavlov, -> #139, bojt
Koji C program ? Može li source, začinjen asemblerom, kao što si već slao za Fortran ?
jezici.141 bojt, -> #140, de.pavlov
>> Koji C program ? Može li source, začinjen asemblerom, kao što >> si već slao za Fortran ? To je onaj kaletov det.c (poruka 6.124), komapjliran Watcom C-om. Za asm kod WC-a nisam primetio opciju koja bi generisala asm source. Pogledaću još malo, mada na kraju uvek ostaje mogućnost da se disasemblira.
jezici.142 bojt, -> #140, de.pavlov
Nisam uspeo da nadjem opciju koja generiše ASM source, tako da uz poruku kačim disasemblirani OBJ DET rutine... detcasm.zip
jezici.143 de.pavlov, -> #141, bojt
> To je onaj kaletov det.c (poruka 6.124), komapjliran Watcom C-om. :) Program koji šaljem kod mene radi brže od kaletovog. Prevedena su oba sa Borland C 3.1 u Large uz uključeno Options\Compiler\Optimizations\Fastest Code. Sve je rađeno na AT286 12 MHz bez koprocesora i generisan je kod za XT. Za dimenziju 50, det.c radi 12.25 sec a detdp.cpp radi 11.70 sec. Nisam uspeo da pokrenem det.c za dimenziju 200, a (za 200) detdp.cpp radi 658.8 sec, i kurioziteta radi Turbo Pascal 7.0 je to (skoro isti kod kao za detdp.cpp) preveo tako da radi 738.3 sec :) Da vidimo sad Watcom C i NDP Fortran :) detdp.zip
jezici.144 bojt, -> #143, de.pavlov
>> Sve je rađeno na AT286 12 MHz bez koprocesora i generisan >> je kod za XT. Hm, da li to znači i da program prikačen uz poruku radi bez koprocesora?
jezici.145 de.pavlov, -> #144, bojt
Rađeno je sa opcijom (+) Emulationa Borland za to kaže : Chose emulation if you want Borland C++ to detect whether your computer has an 80x87 coprocessor ( and to use it if you do, or emulate it if you don't ). HHDakle, trebalo bi da koristi koprocesor ako ga prepozna u mašini, i na ovaj način radi i Turbo Pascal (izgleda da je to osobina Borlandovih prevodilaca koje se oni drže). Probaj da prevedeš onaj source sa Watcom C, ne znam da li se mogu tako lako pronaći prekidači za optimizaciju ali vredi pokušati.
jezici.146 bojt, -> #143, de.pavlov
>> :) >> Program koji šaljem kod mene radi brže od kaletovog. >> Prevedena su oba sa Borland C 3.1 u Large uz uključeno >> Za dimenziju 50, det.c radi 12.25 sec >> a detdp.cpp radi 11.70 sec. Naravno da radi brže od kaletovog, pošto je on pisao det.c imajući u vidu da će ga propuštati kroz njegov UNIX C koji radi u 32-bit protected modu (dakle od 386 pa na više) u kome nema ograničenja sa segmentima a int je četvorobajtni. Od 386 pa naviše tvoj program bi bio inferiorniji od kaltovog, pošto on radi u realnom a ovaj drugi u protected modu (probaću večeras MSC/C++ i Watcom C). U realnom modu, kaletov det.c bi mogao da radi i veće matrice kada bi se koristio huge m.model, brojači proglasili za unsigned i još neke sitnice. Naravno, ti u startu imaš prednost zbog korišćenja pointerskog niza i alociranja vrsta u petlji, čime se isključuje mogućnost da neka vrsta bude jednim delom u jednom a drugim u drugom segmentu. Na kraju, ključna petlja: >> mii = miip; >> brojac = brojacp; >> while (brojac--) >> *(mji++) += *(mii++) * d; je napravljena tako da kompajler maltene i nema šta da optimizuje, a cilj cele diskusije je bio da se uporede optimizatori pojedinih kompajlera.
jezici.147 bojt, -> #145, de.pavlov
>> Rađeno je sa opcijom (+) Emulationa Borland za to kaže : >> Chose emulation if you want Borland C++ to detect whether your >> computer has an 80x87 coprocessor ( and to use it if you do, >> or emulate it if you don't ). Onda najbolje da svoj program uporediš sa zz-ovim CDET.EXE (poruka 6.129). On je napravljen MSC/C++-om 8.00, radi u realnom modu (znači može i XT)i koristi altmath biblioteku (tj isto što i tvoj program), tako da su početni uslovi za oba programa ravnopravna.
jezici.148 bojt, -> #140, de.pavlov
Probao sam DETDP.CPP, i pustio ga kroz MSC/C++ 8.00 i Watcom C, a evo i rezultata: N=200 Realni mod: DETDP TC 3.1 2.41 sec MSDETDP MSC/C++ 8.00 2.30 sec CDET MSC/C++ 8.00 2.80 sec FDET MS Fortran 5.00 2.74 sec FDET1 MS Fortran 5.00 1.92 sec Protected mod (386): FDET MicroWay NDP Fortran 4.0.2 1.26 sec FDET1 MicroWay NDP Fortran 4.0.2 1.28 sec DET (kale) Watcom C 9.01 1.32 sec DETDP Watcom C 9.01 1.38 sec msdet.zip
jezici.150 dgrbic,
Još jedan prilog na temu determinanti. Program radi u protected modu. Nikad nećete pogoditi čime je preveden :) Radi se o C kompajleru. det.exe
jezici.151 bojt, -> #150, dgrbic
>> Još jedan prilog na temu determinanti. Program radi u >> protected modu. Nikad nećete pogoditi čime je preveden :) Radi >> se o C kompajleru. probao sam ga kod mene i evo rezultata: N=200 1.98 sec N=1000 335.05 sec dok MW Fortran daje: N=200 1.26 sec N=1000 223.94 sec
jezici.152 djelovic,
Bojte, ajd' pogledaj kako se ovaj program drži naspram tvog DET-a. cppdet.zip
jezici.154 bojt, -> #152, djelovic
>> Bojte, ajd' pogledaj kako se ovaj program drži naspram tvog DET-a. Otprilike je isto brz kao i DETDP de.pavlov-a. Nisam stigao da probam CPPDET sa MSC/C++ -om 8.00 i Watcom C-om, mada pretpostavljam da bi se dobili slični rezultati. Evo i tabele: N=200, Realni mod: FDET1 ($) MS Fortran 5.00 1.92 sec MSDETDP (de.pavlov) MSC/C++ 8.00 2.30 sec DETDP (de.pavlov) TC 3.1 2.41 sec CPPDET (djelovic) TC 3.1 ??? 2.42 sec FDET ($) MS Fortran 5.00 2.74 sec CDET (zz) MSC/C++ 8.00 2.80 sec Protected mod (386): FDET ($) MicroWay NDP Fortran 4.0.2 1.26 sec FDET1 ($) MicroWay NDP Fortran 4.0.2 1.28 sec DET (kale) Watcom C 9.01 1.32 sec DETDP (de.pavlov) Watcom C 9.01 1.38 sec DET (dgrbic) ???? 1.98 sec
jezici.155 nbatocanin, -> #154, bojt
> FDET1 ($) MS Fortran 5.00 1.92 sec > MSDETDP (de.pavlov) MSC/C++ 8.00 2.30 sec Mogu li ovo da smatram skoro konačnim argumentom u diskusiji o neupotrebljivosti FORTRAN-a ;)
jezici.156 dpredovic, -> #154, bojt
Evo ga det.c kompajliran sa Watcom C/C++32 9.5, u četiri varijante - klot 386, 387, 486 i Pentium. Interesantno je da su svi iste dužine (osim za klot 386, naravno), ali fc pokazuje da razlika stvarno ima... Pošto nemam koprocesor, pojma nemam da li sam im sve svičeve za optimizaciju pogodio kako treba, ima ih stvarno gomila... BTW potreban je dos4gw.exe runtime, ako nemaš - šteta - moraćeš da mi javneš u mail. detw32.exe
jezici.157 dpredovic, -> #154, bojt
Tek sada sam ukapirao da imaš PharLap, evo ih u .exp formatu... phardet.exe
jezici.158 bojt, -> #156, dpredovic
Da, Watcom C 9.5 je nešto brži od verzije 9.01. Evo rezutlata: N=1000 241.18 Watcom C V9.01 /p /oilr /ot /fpi87 (DETDP2.C) 229.26 Watcom C V9.01 /ox /7 (DET.C - kale) 227.72 Watcom C V9.01 /ox /7 /4s /4r (DET.C - kale) 226.62 Watcom C V9.5 (PHAR486.EXP - dpredovic) 223.94 Microway NDP Fortran 486 v4.0.2 (FDET.FOR) 222.45 Microway NDP Fortran 486 v4.0.2 (FDET.FOR) sa ručnom ASM optimizacijom glavne petlje 233.26 Cela ASM rutina pisana ručno 215.31 ASM rutina sa 4 linearne iteracije u petlji 213.99 ASM rutina sa 8 linearnih iteracija u petlji 213.17 ASM rutina sa 16 linearnih iteracija u petlji
jezici.159 omega, -> #155, nbatocanin
Ţ Mogu li ovo da smatram skoro konacnim argumentom u diskusiji o Ţ neupotrebljivosti FORTRAN-a ;) Btw, zasto nigde nije (ako se ne varam) pomenut Lahey Fortran koji je mnoooogo bolji od MS fortrana...?
jezici.160 kriss, -> #158, bojt
˙˙ Da, Watcom C 9.5 je nešto brži od verzije 9.01. Evo rezutlata: (itd.) Nego, da li je neko uzimao odnos (brzina)/(veličina datoteke)? To je (bar zamene) takođe bitan faktor ...
jezici.161 wolf, -> #139, bojt
Zdravo BOJDu, ZZIVOTICu i ostalim programerima u C(++)u i Fortranu. Posto sam juce pokupio celu konferenciju PC.PROG, i video da se vi bas lepo zabavljate sa novim kompajlerima u protected modu, imam par pitanja: 1) Posto vec neko vreme radim iskljucivo sa Watcom C V9.01, a vidim da se brojac zaustavio na V9.5, molio bih za informaciju gde da nabavim ovaj upgrade (ako neko od vas zeli da ucini dobro delo, bicu mu zahvalan). 2) S obzirom da pisem diplomski, i da mi osim Ca trebaju i neke IMSL rutine iz Fortranske biblioteke za numericke proracune, a imam potrebu da radim sa velikim matricama, obradovala me je mogucnost da deo koda mozda necu morati da prevodim na C, pa vas zato pitam koji od C kompajlera moze da se linkuje (iskljucivo me zanima rad u protected modu) sa fortranom (i kojim). Video sam da je MicroWay NDP Fortran 486 V4.0.2 skoro u potpunosti sahranio Watcoma, i zanima me dali slucajno postoji kompatibilnost na nivou .OBJ ova dva kompajlera, i dali to moze da se linkuje. U Watcom-u postoji i Fortran koji ja dosad nisam nigde video, a koji bi mi sigurno omogucio da zavrsim posao. Koji jos tandemi C(++) Fortran, od jednog ili razlicitih proizvodjaca rade u protected modu (osim Watcom Ca i Fortrana). Zainteresovan sam za naba- vku tog famoznog MicroWay NDP Fortran 486 V4.0.2, a s obzirom da ga nema nigde preko oglasa, primoran sam da vam se obratim za pomoc. Ako postoji jos i brzi C kompajler, super. 3) Dali je izasla neka verzija Watcom C++a? Korisnik MAKSA je pominjao neki rad iz oblasti konacnih elemenata u Gradjevini u poruci 6.45 gde je koriscen nekakav Watcom C++. Zar je izasao? 4) Zanima me i koji C kompajler moze da radi sa virtuelnom memorijom, i kakva su vasa iskustva povodom toga. Koji je najbrzi tandem C(++) Fortran za prora- cune i rad na ovom polju (ako ih uopste ima). Pozdrav WOLF!
jezici.162 dejanr, -> #161, wolf
>> 3) Dali je izasla neka verzija Watcom C++a? Postoji Watcom C 10.0. Pravi džin, na 34 diskete po 1.44 mega (ili tako nešto). Kompajlira za svakakve platforme, Novell, ACAD, Windows itd. Što se jezika tiče, u visokoj meri je kompatibilan sa Microsoft C-om, ali razvojna okolina je znatno, znatno siromašnija. Biće, verujem, prikaz u sledećim "Računarima".
jezici.163 bojt, -> #161, wolf
>> Video sam da je MicroWay NDP Fortran 486 V4.0.2 skoro u >> potpunosti sahranio Watcoma Pa, s obzirom da je u slučaju determinante NDP Fortran bio brži nešto preko 1%, ne bih baš rekao da ga je "sahranio". Priča je i počela oko rasprave koliko su dobri optimizatori ugradjeni u pojedine kompajlere. Ispostavilo se da su MW NDP F i Watcom C po tom pitanju skoro identični, što je u teorijskom smislu bilo i za očekivati od kompajlera koji slove za "industry standard". Takodje se ispostavilo da pisanje posebne ASM rutine za izračunavanje determinante čitavu stvar ubrzava jedva za nekih 5%. >> i zanima me dali slucajno postoji kompatibilnost na nivou .OBJ >> ova dva kompajlera, i dali to moze da se linkuje. U Watcom-u >> postoji i Fortran koji ja dosad nisam nigde video, a koji bi >> mi sigurno omogucio da zavrsim posao. Koji jos tandemi C(++) >> Fortran, od jednog ili razlicitih proizvodjaca rade u >> protected modu (osim Watcom Ca i Fortrana). Izmedju NDP Fortrana i Watcom C-a ne postoji kompatibilnost ni na nivou OBJ-a ni na nivou LIB-ova. Postoji Watcom Fortran, kao i MicroWay NDP C/C++ i oni se lako uklapaju sa odgovarajućim kompajlerima istog proizvodjača (obično, pored C-a i Fortrana postoji i Pascal). Na žalost, ne znam nikog na ovim prostorima ko ima Watcom Fortran ili MW NDP C.
jezici.164 de.pavlov,
Uz poruku je program detdp2.c, više sa kozmetičkim promenama u odnosu na detdp.c koji sam pre poslao. Evo nekih rezultata : računar 80286 12 MHz, bez koprocesora ( svuda je korišćena emulacija iz prevodioca ) n = 50 Microsoft C 8.0 detdp.c 14.23 sec. Borland C 3.1 detdp2.c 11.70 sec. fdet1.for 8.46 sec. <-- Zortech C 3.0 detk.c 8.02 sec. <-- Zortech C 3.0 detdp2.c 7.96 sec. <-- n = 200 Borland C 3.1 detdp2.c 658,52 sec. fdet1.for 503,89 sec. <-- Zortech C 3.0 detdp2.c 454,23 sec. <-- C je pretekao Fortran u konkurenciji sa emulacijom koprocesora i kodom za XT. Obratite pažnju na Zortech-ovu izuzetnu emulaciju koprocesora. žini se da su se iskristalisale kategorije računara u kojima se radilo poređenje C - Fortran : - generisan kod za XT, emulacija koprocesora - generisan kod za XT, inline koprocesor kod - generisan kod za protected ( 386 ), inline koprocesor kod Gledano po ovome, rezultat je 2 : 1, na poene :) , za Fortran. Zadatak je bio jedan od najjednostavnijih - računanje determinante. Nešto malo umetnutih for petlji, u petljama jednostavan račun, i to je sve. Reklo bi se, programska složenost zadatka maksimalno na ruku Fortranu. Ipak, zarad svetske istine :) , trebalo bi testirati prevodioce na, za bar dva reda veličine, složenijem problemu - kada kažem složenijem mislim pre svega na programski složeniji a ne numerički intenzivniji :) , a složenost programa će dovesti i do dugog izvršavanja :) U samom algoritmu koji je dao bojt , može se na dva mesta uraditi poboljšanje, tada bi svi programi ( i C i Fortran ) bili brži. Izmene su date u detdp3.c , uz poruku. U drugoj petlji ( po dubini ) je izvučeno -1 izvan petlje, a u petlji za izbor glavnog elementa smanjen je broj računanja fabs. Ove dve izmene su donele mala ubrzanja : n = 200 , 80286 12 MHz, bez koprocesora Borland C 3.1 detdp2.c 658,52 sec. Borland C 3.1 detdp3.c 656,76 sec. Evo šta su neki C prevodioci uradili od detdp2.c Date su disasemblirane .obj datoteke za dve najdublje petlje u proceduri "determinanta". (-----------------------------------------------------------------) Borland C 3.1, radi na XT, emulacija koprocesora, ( isti kod daje i sa inline 8087 kod ) Fastest Code optimizacija ; for (j = (i + 1); j <= n; j++) ; ?debug L 64 mov ax,word ptr [bp-42] mov word ptr [bp-4],ax mov cx,word ptr [bp+6] push cx mov cl,2 shl ax,cl pop cx add cx,ax jmp short @1@674 @1@478: ; ; { ; mji = &(**((*mat)+(j)))[i]; ; ?debug L 66 mov es,word ptr [bp+8] mov bx,cx mov ax,word ptr es:[bx+2] mov dx,word ptr es:[bx] add dx,word ptr [bp-40] mov word ptr [bp-24],ax mov word ptr [bp-26],dx ; ; d = - *mji * c; ; ?debug L 67 les bx,dword ptr [bp-26] fld qword ptr es:[bx] fchs fmul qword ptr [bp-14] fstp qword ptr [bp-22] ; ; if (d != 0) ; ?debug L 68 fld qword ptr [bp-22] fldz fcompp fstsw word ptr [bp-36] fwait mov ax,word ptr [bp-36] sahf je short @1@618 ; ; { ; mii = miip; ; ?debug L 70 mov ax,word ptr [bp-32] mov dx,word ptr [bp-34] mov word ptr [bp-28],ax mov word ptr [bp-30],dx ; ; ; for (k = (i + 1); k <= n; k++) ; ?debug L 72 mov si,word ptr [bp-42] jmp short @1@590 @1@534: ; ; { ; *(++mji) += *(++mii) * d; ; ?debug L 74 add word ptr [bp-26],8 add word ptr [bp-30],8 les bx,dword ptr [bp-30] fld qword ptr es:[bx] fmul qword ptr [bp-22] les bx,dword ptr [bp-26] fadd qword ptr es:[bx] fstp qword ptr es:[bx] fwait ?debug L 72 inc si @1@590: cmp si,di jle short @1@534 @1@618: ?debug L 64 add cx,4 inc word ptr [bp-4] @1@674: cmp word ptr [bp-4],di jle short @1@478 (-----------------------------------------------------------------) Zortech C 3.0 radi na XT emulacija koprocesora speed optimizacija L234: mov AX,-010h[BP] les BX,-01Ah[BP] mov DX,ES:2[BX] mov BX,ES:[BX] add BX,AX mov -02Ch[BP],DX mov -02Eh[BP],BX mov ES,DX mov SI,BX mov AX,ES:6[SI] mov CX,ES:2[SI] mov DX,ES:[SI] mov BX,ES:4[SI] xor AH,080h push AX push BX push CX push DX mov AX,-038h[BP] mov BX,-03Ah[BP] mov CX,-03Ch[BP] mov DX,-03Eh[BP] call far ptr __DMUL@ mov -030h[BP],AX mov -032h[BP],BX mov -034h[BP],CX mov -036h[BP],DX shl AX,1 or AX,BX or AX,CX or AX,DX je L300 mov DX,-024h[BP] mov AX,-026h[BP] mov -028h[BP],DX mov -02Ah[BP],AX mov AX,-012h[BP] mov -040h[BP],AX cmp AX,0Ah[BP] jg L300 L2A1: mov SI,8 add -02Eh[BP],SI les DI,-02Eh[BP] push ES:word ptr 6[DI] push ES:word ptr 4[DI] push ES:word ptr 2[DI] push ES:[DI] push ES add -02Ah[BP],SI les BX,-02Ah[BP] push ES:word ptr 6[BX] push ES:word ptr 4[BX] push ES:word ptr 2[BX] push ES:[BX] mov AX,-030h[BP] mov BX,-032h[BP] mov CX,-034h[BP] mov DX,-036h[BP] call far ptr __DMUL@ pop ES call far ptr __DADD@ mov ES:6[DI],AX mov ES:4[DI],BX mov ES:2[DI],CX mov ES:[DI],DX inc word ptr -040h[BP] mov AX,-040h[BP] cmp AX,0Ah[BP] jle L2A1 L300: add word ptr -01Ah[BP],4 inc word ptr -042h[BP] mov AX,-042h[BP] cmp AX,0Ah[BP] jg L312 jmp near ptr L234 (-----------------------------------------------------------------) Zortech C 3.0 radi na XT In Line 8087 speed optimizacija L18C: mov AX,-010h[BP] les BX,-01Ah[BP] mov DX,ES:2[BX] mov BX,ES:[BX] add BX,AX mov -02Ch[BP],DX mov -02Eh[BP],BX mov ES,DX mov SI,BX wait fnld qword ptr ES:[SI] fchs fmul qword ptr -03Eh[BP] fstp qword ptr -036h[BP] wait mov AX,-030h[BP] shl AX,1 or AX,-032h[BP] or AX,-034h[BP] or AX,-036h[BP] je L207 mov DX,-024h[BP] mov AX,-026h[BP] mov -028h[BP],DX mov -02Ah[BP],AX mov AX,-012h[BP] mov -040h[BP],AX cmp AX,0Ah[BP] jg L207 L1DC: mov AX,8 add -02Ah[BP],AX les BX,-02Ah[BP] wait fnld qword ptr ES:[BX] fmul qword ptr -036h[BP] add -02Eh[BP],AX les BX,-02Eh[BP] wait fnadd qword ptr ES:[BX] wait fnstp qword ptr ES:[BX] wait inc word ptr -040h[BP] mov AX,-040h[BP] cmp AX,0Ah[BP] jle L1DC L207: add word ptr -01Ah[BP],4 inc CX cmp CX,0Ah[BP] jg L214 jmp near ptr L18C (-----------------------------------------------------------------) Watcom C 9.01 radi na 386 In Line 80387 /oilr /ot optimizacija L8: mov edx,dword ptr [edi] add edx,dword ptr -14H[ebp] fld qword ptr [edx] fchs fmul st,st(2) fstp st(1) ftst fstsw ax sahf je short L10 mov eax,dword ptr -4H[ebp] mov ebx,dword ptr -0cH[ebp] cmp ecx,eax jl short L10 L9: fld st(0) add ebx,00000008H fmul qword ptr [ebx] add edx,00000008H fadd qword ptr [edx] inc eax fstp qword ptr [edx] cmp eax,ecx jle short L9 L10: inc esi add edi,00000004H cmp esi,ecx jle short L8 detdp23.zip
jezici.165 nbatocanin, -> #161, wolf
> U Watcom-u postoji i Fortran koji ja dosad nisam nigde > video, a koji bi mi sigurno omogucio da zavrsim posao. Ja video i radio sa jednom verzijom pre nekoliko godina. Ima strašan jezik i ekstenzije - po konstrukcijama je tada bio jači od VMS FORTRAN-a. Što se tiče koncepcije prevođenje-linkovanje, sećam se samo da je bilo nešto nestandardno. Ako bi se potrudio, možda bih mogao da nađem i uputstvo a možda i sam softver, al' ne garantujem.
jezici.166 bojt, -> #164, de.pavlov
E, ovaj DETDP3.C je nešto posebno! EXE koji sam dobio koristeći MSC/C++ 8.00 bio je brži od svega što sam do sada video u domenu realnog moda. Determinantu reda 200 uradio je za 1.81 sec, čime je pretekao FDET1 koji je isti posao radio za 1.92 sec. Morao sam da se veoma napnem da bi ga, raznim trikovima (nebili kompajleru bilo lakše da generiše brži kod), nekako pretekao. Sve to dovodi do velikih odstupanja od prbobitnog, jedonstavnog source-a, a samim tim od incijalne ideje da se ispita kvalitet optimizacije pojedinih kompajlera. Medjutim, imajući u vidu činjenicu da su trenutini C kompajleri koji generišu kod koji radi u realnom modu (MSC 8.00 na primer) daleko savremeniji i doradjeniji od fortranskih ekvivalenata (koji se daleko redje noveliraju), kao i činjenicu da se pomoću pointerskih nizova obezbedjuje rad programa u Large memorijskom modelu (alocira vrstu po vrstu pa se nijedna od njih se ne prostire izvan jednog segmenta), čime se izbegava sporiji rad u Huge modelu, moram da priznam da sam se uverio da je pomoću C-a u svakom slučaju moguće napraviti brži program nego u Fortranu. Evo i rezultata: N=200, realni mod DET.C MSC/C++ 8.00 /AL /Gs /O2 /FPi87 3.35 sec CDET.C MSC/C++ 8.00 2.80 sec FDET.FOR MS Fortran 5.00 2.74 sec DETDP.C TC 3.1 2.41 sec MSDETDP.C MSC/C++ 8.00 2.30 sec FDET1.FOR MS Fortran 5.00 1.92 sec DETDP3.C MSC/C++ 8.00 /AL /Gs /O2 1.87 sec DETDP3.C MSC/C++ 8.00 /AL /Gs /O2 /FPi87 1.81 sec FDET2.FOR MS Fortran 5.00 1.75 sec U protected modu, gde nema ograničenja u vidu segmenata od 64K, kada se radi o C-u, rad preko pointerskih nizova definitivno daje sporije rezultate nego direktno pristupanje matrici (DET.C - kale). U odnosu na Fortran, do sada nijedna varijanta C source-a kompajlirana Watcom C-om nije uspela da pobedi prvobitni FDET kompajliran MicroWay Fortranom. N=1000 DETDP2.C Watcom C V9.01 /p /oilr /ot /fpi87 241.18 DETDP3.C Watcom C V9.01 /ox /7 /4s /4r 239.31 DET.C Watcom C V9.01 /ox /7 229.26 DET.C Watcom C V9.01 /ox /7 /4s /4r 227.72 DET.C Watcom C V9.5 (PHAR486.EXP) 226.62 FDET.FOR Microway NDP Fortran 486 v4.0.2 223.94 FDET.FOR Microway NDP Fortran 486 v4.0.2 222.45 (sa ručnom ASM optimizacijom glavne petlje) Cela ASM rutina pisana ručno 233.26 ASM rutina sa 4 linearne iteracije u petlji 215.31 ASM rutina sa 8 linearnih iteracija u petlji 213.99 ASM rutina sa 16 linearnih iteracija u petlji 213.17 Uz poruku DETDP3E.EXE i FDET2.EXE, oba rade i bez koprocesora. dp3exe.zip
jezici.167 de.pavlov, -> #166, bojt
> sam da se veoma napnem da bi ga, raznim trikovima (nebili > kompajleru bilo lakše da generiše brži kod), nekako pretekao. Može li malo detalja o gornjem ? ( kakav ti je sada izvorni kod, koje prekidače si koristio u prevođenju, itd. )
jezici.168 dpredovic, -> #161, wolf
> 3) Dali je izasla neka verzija Watcom C++a? Korisnik MAKSA je > pominjao neki rad iz oblasti konacnih elemenata u Gradjevini u > poruci 6.45 gde je koriscen nekakav Watcom C++. Zar je izasao? > > 4) Zanima me i koji C kompajler moze da radi sa virtuelnom > memorijom, i kakva su vasa iskustva povodom toga. Koji je > najbrzi tandem C(++) Fortran za prora- cune i rad na ovom polju > (ako ih uopste ima). Odgovor na oba pitanja je Watcom C/C++ 9.5 BTW, Trebao bi da izađe i 10.0, sada je valjda u beta-fazi...
jezici.169 zeljkoj,
Interesuje me da li postoji (da li je postojao :)) ALGOL kompajler za PC.
jezici.170 dejanr,
[Odgovor na PC.PROG/pascal 7.413, djelovic] >> Koncept skrivanja informacija ne služi da bi proizvođač krio >> svoje tajne, već da bi svaki modul imao jasno definisan interfejs. Interfejs je jednako jasno definisan ako kažeš "vrednost se postavlja sa 'postavi_vrednost (xxx, 5)' i kada kažeš 'xxx=5'. Po pitanju definisanosti nema razlike, po pitanju efikasnosti obično ima. U korist direktne dodele vrednosti. Stvar je u nečemu drugome: ako je modul "zatvoren" na taj način, njegov autor može da menja njegovo interno funkcionisanje kako god želi, sve dok "prema svetu" interfejs ostane isti. U konkretnom primeru, uz dodelu vrednosti promenljivoj xxx u proceduri postavi_vrednost može da uradi još neke stvari, da inicijalizuje neku internu promenljivu i tome slično. Ako je promenljivu ostavio kao globalnu, takvu kontrolu više nema, pa je prilično omeđen što se promena u svom modulu tiče. Sve ovo je jako lepo i krasno, ako je u pitanju neki veliki projekat koji radi više programera. Ali, ako čovek sam sedi i piše program, prilično gubi smisao (ne baš sasvim, ali prilično). To je isto kao kada neko kaže "objektno programiranje je neophodno, jer strukturirano postaje nemoguće za održavanje već kod projekata od 100,000 linija koda". Ili, jednoga dana, "intravenozno programiranje je neophodno, jer objektno postaje nemoguće za održavanje već kod projekata od 1,000,000 linija koda". Sve to čita neko ko piše isključivo programe od, recimo, 4-5,000 linija koda i od njih sasvim lepo živi, i sasvim sa pravom kaže "e baš me briga" :) Da ne bih bio jednostran, da navedem i jedan argumenat u korist "druge strane": to što je xxx=5 efikasnije od postavi_vrednost (xxx, 5) je problem lošeg optimizacionog kompajlera. Dobar optimizacioni kompajler će to (ako ne sada, a ono jednoga dana :) prevesti u praktično isti kod.
jezici.171 djelovic, -> #170, dejanr
> Interfejs je jednako jasno definisan ako kažeš "vrednost se postavlja > sa 'postavi_vrednost (xxx, 5)' i kada kažeš 'xxx=5'. Po pitanju > definisanosti nema razlike, po pitanju efikasnosti obično ima. U korist > direktne dodele vrednosti. Dobro, de, izraz "jasno definisan infterfejs" koristio sam da bih zapakovao krupne reči kao što su kapsulacija, apstrakcija i sl. Pošto si i sam primetio da uz inline funkcije ne bi trebalo da bude razloga za razlike u brzini (BTW inline imaju svi noviji C/C++ kompajleri), onda ću samo da primetim da "x=5" i "postavi (x, 5)" nije isto - prvo može da se uradi bilo kada i da time poremeti neku operaciju koja je stigla do pola, a drugo bi u tom slučaju moglo da javi grešku. > Stvar je u nečemu drugome: ako je modul "zatvoren" na taj način, njegov > autor može da menja njegovo interno funkcionisanje kako god želi, sve > dok "prema svetu" interfejs ostane isti. Naravno, i to stoji. Menjanje interfejsa izaziva menjanje i prevođenje svih modula koji od njega zavise, i samim tim je daleko skuplje od menjanja detalja implementacije. > Sve ovo je jako lepo i krasno, ako je u pitanju neki veliki projekat koji > radi više programera. Ali, ako čovek sam sedi i piše program, prilično > gubi smisao (ne baš sasvim, ali prilično). To je isto kao kada neko kaže > "objektno programiranje je neophodno, jer strukturirano postaje nemoguće > za održavanje već kod projekata od 100,000 linija kodů┴9- Pa naravno, i sam si svojevremno demonstrirao da je za pisanje "Hello, world!" programa najbolji Bejzik :). Nekih par stotina linija koda svako može da napiše na bilo koji način, koristeći promenljive sa imenima kao što su "jelena", "tanja" i "marina" :), bez potprogram i sl. Kako program raste, tako to postaje sve teže i teže. Ja lično ne imam velike muke da protumačim svoj prljavi kod već par meseci pošto ga nisam dirao, te mislim da se "lepo" programiranje isplati i na programima od 3-5000 linija koje ti spominješ :). Obaška što dobro napisan modul možeš i kasnije da iskoristiš u drugim programima :).
jezici.172 goxx, -> #171, djelovic
■ Ja lično ne imam velike muke da protumačim svoj prljavi kod već par ■ meseci pošto ga nisam dirao, te mislim da se "lepo" programiranje ■ isplati i na programima od 3-5000 linija Ovde se u potpunosti slažem. "Ružno" programiranje koristim na test programima i to samo do 50 linija :) Goran
jezici.173 goxx,
Odgovor na 7.415 iz teme pascal, mmitrovic ■ Recimo da si u pravu, i nazovimo to (u nedostatku boljeg izraza) ■ čistim programiranjem. žisto programiranje nije i efikasno programiranje Šta podrazumevaš pod efikasnim programiranjem. Ako se, na primer, x=5 izvršava za stoti deo sekunde brže od postavi(x,5), a ja imam sto puta dodelu vrednosti preko funkcije to znači da će mi program biti sporiji za jednu sekundu. Toliko sam spreman da žrtvujem zarad čistog programiranja. (Drugi aspekt efikasnosti osim vremena ja i ne vidim) Da i ja nešto dodam. Pošto trenutno radim sa clipper-om opisaću ukratko kako sve to izgleda u njemu. Na primer u clipperu postoji deklaracija PUBLIC kojom se promenljivoj daje životni vek tokom celog programa iz bilo koje funkcije. Međutim, ona postoji samo da bi se održala kompatibilnost sa starom verzijom jezika. Gledajući jedan modul, možemo da razdvojimo promenljive prema nameni. Ako je promenljiva potrebna samo za čuvanje vrednosti, a ne koristi se nigde u modulu, onda se ona stavlja kao STATIC u jednoj funkciji tipa postavi(5). / Clipper tu ima jednu prednost nad drugim jezicima. Pošto ne postoji stroga kontrola tipa promenljivih funkcija bi mogla da se poziva na dva načina vrednost_x() i vrednost_x(5). U prvom slučaju se očitava vrednost promenljive koja je "zatvorena" u funkciji, a u drugom joj se pored očitavanja i dodeljuje vrednost. / U drugu vrstu promenljivih bi mogle da uđu one koje se koriste samo u modulu i to u više funkcija modula. One se postave kao STATIC van svih funkcija i koriste se u modulu direktno (x=5). Ako je potrebno da jedna takva promenljiva bude dostupna i van modula (rekli smo da bi na početku aplikacije mogla da se postavi sa PUBLIC) dovoljno je da i njoj napravimo funkciju tipa postavi_ocitaj(). 1. promenljiva se stavlja na novu vrednost samo ako je došla nova vrednost, a uvek vraća staru vrednost (x "vidljivo" samo u f-ji) FUNCTION Vrednost_X ( vrednost ) STATIC x := neka_pocetna_vrednost LOCAL y := x IF vrednost <> NIL x := vrednost ENDIF RETURN y 2. ako se promenljiva koristi samo u modulu u vise funkcija STATIC x := neka_pocetna_vrednost ... u funkcijama se koristi x := ... 3. kombinacija 1. i 2. promenljiva se koristi i u modulu (kao pod 2.) i van modula STATIC x := neka_pocetna_vrednost ... u funkcijama se koristi x ... (a može i Vrednost_X(... ) ... FUNCTION Vrednost_X ( vrednost ) LOCAL y := x IF vrednost <> NIL x := vrednost ENDIF RETURN y Skoro sam čitao u nekom članku sa sezama da se sve više teži baš ovakvom "zatvaranju" promenljivih (bilo je i u clipper savetniku u Računarima). Ovo bi moglo da ide i u clipper konferenciju, ali može da bude korisno i za druge jezike. Goran
jezici.174 dejanr, -> #171, djelovic
>> Ja lično ne imam velike muke da protumačim svoj prljavi kod već >> ^^^^^^^ >> par meseci pošto ga nisam dirao ??? >> te mislim da se "lepo" programiranje isplati i na programima od >> 3-5000 linija koje ti spominješ :). Lepo programiranje... da. Razne kapsulacije, apstrakcije, objekti itd... verovatno ne. Inače, (formalno) "ružno pisani" program može da bude mnogo lakši za praćenje od nekog "lepo pisanog". Samo kad vidiš silne else-ove i ugnježdene if-ove, samo da bi se izbeglo jedno jasno i jednostavno goto... ;)
jezici.175 dejanr, -> #173, goxx
>> Pošto trenutno radim sa clipper-om opisaću ukratko kako sve to izgleda >> u njemu. Na primer u clipperu postoji deklaracija PUBLIC kojom se >> promenljivoj daje životni vek tokom celog programa iz bilo koje funkcije. >> Međutim, ona postoji samo da bi se održala kompatibilnost sa starom >> verzijom jezika. Hmmm... ne baš samo zato. Ima na Clipperu stvari za koje su PUBLIC varijable i dalje praktično neophodne. Nešto od toga može da se reši sa kodnim blokovima i (naročito) makro operatorom (mada ja nekako više volim public promenjive nego makro operator ;) ali... Ako si čitao Rick Spence-a, video si da maltene "pola knjige" ode na to da se opiše kako u raznim situacijama izbeći public varijablu i makro operator... negde zaista na zgodan način, a negde totalno veštački. Ponegde ni on nije uspeo. Osim toga, ima stvari koje prosto "plaču" za public varijablama. Recimo, trenutni username korisnika može da bude potreban u deset raznih modula, ko da ga svaki čas prenosi kao parametar? Ovako definišeš promenljive MYNAME, MYRIGHTS, MYCOLOR i tako dalje, staviš da su PUBLIC, u svim modulima include-uješ neki fajl u kome piše da su MYNAME itd memvar promenljive i sve fino radi. Inače, sasvim se slažemo da je u većini slučajeva LOCAL i STATIC daleko bolje (obaška što je racionalnije) rešenje od PRIVATE i PUBLIC. Ali ne uvek!
jezici.176 djelovic, -> #174, dejanr
> >> Ja lično ne imam velike muke da protumačim svoj prljavi kod već > >> ^^^^^^^ > >> par meseci pošto ga nisam dirao > > ??? "Ne" je slučajno uletelo. > Inače, (formalno) "ružno pisani" program može da bude mnogo lakši za > praćenje od nekog "lepo pisanog". Samo kad vidiš silne else-ove i > ugnježdene if-ove, samo da bi se izbeglo jedno jasno i jednostavno > goto... ;) Da, svi pričaju da goto naredbu ne treba koristiti, iako postoje situacije u kojima je ta naredba sasvim legitimna. Recimo za izlazak iz dve (ili više) ugnježdene petlje.
jezici.177 pedjak, -> #170, dejanr
> za održavanje već kod projekata od 1,000,000 linija koda". Sve to > čita neko ko piše isključivo programe od, recimo, 4-5,000 linija > koda i od njih sasvim lepo živi, i sasvim sa pravom kaže "e baš me > briga" :) Hm, ne bih se baš složio :) Ovde se u krajnjem slučaju priča o samoj kulturi pisanja programa - što čistije, to bolje :) Ja već posle mesec-dva teško kapiram neki svoj prljavo napisani program. Obaška to, što kvalitetno napisan modul možeš iskoristiti u nekom svom drugom programu.
jezici.178 pedjak,
CONF REPLY 7.415/mmitrovic > čistim programiranjem. žisto programiranje nije i efikasno > programiranje, zbog razloga koje sam već naveo. Ne postoje apsolutno > nijedan dobar razlog zbog koga bi trebalo sakrivati promenljive od > samog sebe. Specijalno one koje se koriste u višim modulima i u > samom Pa sad, nije efikasno po pogledu brzine izvršavanja, ali ako želiš brz program, asembler u ruke :) Međutim, čisto programiranje je efikasno po pitanju održavanja koda i njegovog lakog menjanja, a da to ostatak programa vrlo malo ili čak nimalo ne oseti. > To je bilo pre nekih 6 meseci dok sam se zanosio da napravim Graphic > Vision :) Silly of me. Pre nekog vremena videh tako nešto...
jezici.179 zormi,
Jel' neko radio sa MS FORTRAN POWERSTATION? Dobio sam taj paket i izgleda zanimljivo, ali nemam pri ruci nijedan dobar Fortran source za testiranje. Interesantno je da sam compiler (tj. kompletna radna okolina) radi pod MS Windows, a generiše se EXE koji radi pod DOS-om u protected modu (priložen je DOS extender).
jezici.180 omega, -> #178, pedjak
Ţ> To je bilo pre nekih 6 meseci dok sam se zanosio da napravim Graphic Ţ> Vision :) Silly of me. Ţ Ţ Pre nekog vremena videh tako nesto... Source?
jezici.181 dr.grba, -> #173, goxx
>> Skoro sam čitao u nekom članku sa sezama da se sve više teži baš >> ovakvom "zatvaranju" promenljivih (bilo je i u clipper savetniku >> u Računarima). Sasvim jasno: jedan od osnovnih principa modularnog programiranja je upravo uvođenje reda među promenljive. PUBLIC promenjlive se ne uklapaju u tu koncepciju.
jezici.182 mdrazic, -> #181, dr.grba
> Sasvim jasno: jedan od osnovnih principa modularnog > programiranja je upravo uvođenje reda među promenljive. > PUBLIC promenjlive se ne uklapaju u tu koncepciju. Pošto je jedino mesto gde deklarišem PUBLICe u osnovnom (vrlo kratkom) modulu, može li se shvatiti da (bar u mom slučaju) ovi PUBLICi predstavljaju STATICe za sve sorsove zajedno, tj celu aplikaciju? ;) Šalu na stranu, postoji bitna razlika kako se manipuliše public, private sa jedne strane i static, local promenljivima sa druge strane. Ima li neko neku literaturu o tome? Već nekoliko godina vidim da postoji naslov "Dynamics of Clipper" ali više od toga ne znam. Interesantna je potrošnja memorije, brzina pristupa promenljivoj itd. Milan
jezici.183 mdrazic, -> #176, djelovic
> Da, svi pričaju da goto naredbu ne treba koristiti, iako > postoje situacije u kojima je ta naredba sasvim legitimna. > Recimo za izlazak iz dve (ili više) ugnježdene petlje. Lepa je konstrukcija za ovo u Clipperu: begin sequence ... ... petlje itd break ... petlje itd ... ŠrecoverĆ ... ... end sequence ... Najlepše od svega je da break izlazi iza recover ili end sequence bilo u istom modulu ili u prvom od modula sa steka poziva u kome se ovo nalazi (praktično: u nekom drugom modulu, tj. prg fajlu). Kao primer da nije uvek lako bez prljavih trikova (goto i sl.) završiti neki posao je sledeći zadatak: Imate dva sortirana fajla. Zadatak je u treći fajl zapisati sortirani sadržaj oba ulazna fajla zajedno (merdžovanje parcijalno sortiranih listi). U starom FORTRANU to ide sa daleko manje komandi nego recimo u Pascalu. Milan
jezici.184 mdrazic, -> #179, zormi
> Jel' neko radio sa MS FORTRAN POWERSTATION? > > Dobio sam taj paket i izgleda zanimljivo, ali nemam pri > ruci nijedan dobar Fortran source za testiranje. > Interesantno je da sam compiler (tj. kompletna radna > okolina) radi pod MS Windows, a generiše se EXE koji radi > pod DOS-om u protected modu (priložen MS FORTRAN 5.1 može i da piše programe za Windowse. Ali, nije to ono pravo, već da u raznim prozorima pratiš recimo sadržaj više izlaznih datoteka. Izlaz je i dalje ASCII, samo radi u prozorima. Inače sam veoma zainteresovan za testiranje :) ovog paketa ako nije teško da se negde nađemo. Milan
jezici.185 mmitrovic, -> #173, goxx
Ů█▀█Ţ x=5 izvršava za stoti deo sekunde brže od postavi(x,5), a ja imam Ů█▀█Ţ sto puta dodelu vrednosti preko funkcije to znači da će mi program Ů█▀█Ţ biti sporiji za jednu sekundu. Toliko sam spreman da žrtvujem zarad Da, ali ako imaš 10000 dodela to ti je 1min 40sec, a tek za 100000 dodela. Ne retko imam potrebu za takvim stvarima u teškim iteracijama i rekurzijama. Sam si rekao da pišeš u CLIPPERu a tamo za takve stvari nema potrebe, tako da tebi dodela može da bude stoput sporija nego u pascalu ili Cu. Ne kažem da je izolovanost modula loša stvar, čak šta više mnogi moduli i objekti se tako štite od kritičnih vrednosti (primer, deljenje sa 0). Međutim, ako sam pišeš programe i module, globalne promenljive su ti potrebne samo ako više modula koristi istu promenljivu, što se vrlo retko sreće u većim količinama. Nije neki problem zapamtiti tri promenljive (ili čak ubaciti komentar čemu služe) nego se zamajavati procedurama koje će u sebi imati samo jedno x:=vred;
jezici.186 dejanr, -> #182, mdrazic
>> Šalu na stranu, postoji bitna razlika kako se manipuliše >> public, private sa jedne strane i static, local promenljivima >> sa druge strane. Ima li neko neku literaturu o tome? Ne znam na koliko detaljnu literaturu misliš. Rick Spence u svojoj poznatoj knjizi dosta piše o tome, ali ne ide baš u detalje koliko bajtova šta troši.
jezici.187 goxx, -> #175, dejanr
■ blokovima i (naročito) makro operatorom (mada ja nekako više volim public ■ promenjive nego makro operator ;) ali... Ako si čitao Rick Spence-a, video Iskreno rečeno, ne volim ni jedne ni druge :) ... ■ si da maltene "pola knjige" ode na to da se opiše kako u raznim situacijama ■ izbeći public varijablu i makro operator... negde zaista na zgodan način, ■ a negde totalno veštački. Ponegde ni on nije uspeo. ..., ali ih i ja upotrebljavam kad stvarno ništa drugo ne uspe. ■ ko da ga svaki čas prenosi kao parametar? Ovako definišeš promenljive ■ MYNAME, MYRIGHTS, MYCOLOR i tako dalje, staviš da su PUBLIC, u svim modulima Kod mene bi verovatno bilo MyName(), MyRights(), MyColor()... u modulu My.prg (šta kažeš, tvrdo krilo, a :)) ?). Šalu na stranu, nisam siguran da mi možda sutra neće pasti na pamet da pored x := MYRIGHTS uradim i još nešto, ali ako sam sto posto siguran da neće, onda i ja grešim dušu sa nekim PRIVATE u glavnom modulu :). Goran
jezici.188 bojt,
Probao sam (thanks to zormi) Microsoft Fortran PowerStation v1.00. Stiže na 3 1.44 diskete i može da se instalira samo preko Windows-a, dok je kasnije moguće pokretati kompajler iz DOS-a i praviti programe koji mogu da rade samo pod DOS-om. U samim windows-ima dobije se "Fortran Visual Workbench", iz čega pratično može da se radi sve, ali pošto ja nekako ne volim win, samo sam ovlaš pogledao šta sve i ima i malo koristio help. Pod DOS-om stvar izgleda u dobroj meri ista kao i kod real-mode MS Fortrana 5.0 ili 5.1. Kompajler može da generiše kod za 386 ili 486, dobar deo opcija je nasledjen od prethodnika, mada je od optimizacionih opcija ostalo samo: /Ox optimize for time /Op improve floating-point consistency Kao rezultat kompajliranja i linkovanja dobija se EXE fajl sa ugradjenim DOS-extenderom koji je za više od dva reda veličine kraći od EXE fajla koji se BIND opcijom dobija iz, na primer, MicroWay NDP Fortrana, što je za svaku pohvalu (FDET.EXE je, na primer, dugačak 108K kod MS, a 231K kod NDP fortrana). Naravno, odmah sam "probao" program za determinantu, pošto je o tome ovde bilo dosta reči. Koristeći opcije /G4 /Gs /Ox (/G4 - i486 instructions, /Gs - disable stack checking, /Ox - optimize for time), dobijao se najbrži kod, medjutim odmah se pokazalo da postoje znatne razlike u brzini u zavisnosti od toga da li se u fortranskom izvornom kodu matrica alocira statički ili dinamički. Naime, prvo sam determinantu probao statički alocirajući matricu sa REAL*8 A(1000,1000) (pošto nisam bio siguran da li je ostao isti princip dinamičke alokacije kao kod MSF5.0, a tamo je bilo i neke petljancije sa mem.modelima). U toj varijanti je postignut do sada najbolji rezultat za N=200 (1.16sec), dok je za N=1000 rezultat je bio na nivou Watcom C-a 9.5 (226sec). Kada sam primenio dinamičku alokaciju na moje iznenadjenje program je radio osetno sporije. Kod NDP Fortrana, na primer, nije bilo tog fenomena. Tabela izgleda ovako: N=1000, protected mode DETDP2.C Watcom C V9.01 /p /oilr /ot /fpi87 241.18 FDET.FOR MS Fortran PowerStation V100 /Ox /G4 /Gs 239.42 (dynam.) DETDP3.C Watcom C V9.01 /ox /7 /4s /4r 239.31 DET.C Watcom C V9.01 /ox /7 229.26 DET.C Watcom C V9.01 /ox /7 /4s /4r 227.72 FDET.FOR MS Fortran PowerStation V100 /Ox /G4 /Gs 226.68 (static) DET.C Watcom C V9.5 (PHAR486.EXP) 226.62 FDET.FOR Microway NDP Fortran 486 v4.0.2 223.94 FDET.FOR Microway NDP Fortran 486 v4.0.2 222.45 (sa ručnom ASM optimizacijom glavne petlje) Cela ASM rutina pisana ručno 233.26 ASM rutina sa 4 linearne iteracije u petlji 215.31 ASM rutina sa 8 linearnih iteracija u petlji 213.99 ASM rutina sa 16 linearnih iteracija u petlji 213.17 dok je za N=200 DETDP Watcom C 9.01 1.38 DETDP2 Watcom C 9.01 1.37 DET (kale) Watcom C 9.01 1.32 FDET MicroWay NDP Fortran 4.0.2 1.26 FDET MS Fortran PowerStation V100 /Ox /G4 /Gs 1.26 (dynam.) FDET MS Fortran PowerStation V100 /Ox /G4 /Gs 1.16 (static) "Glavna petlja" kod ovog fortrana je dosta interesantna. Nema trikova sa 4 (ili više) iteracija u petlji, medjutim: jmp SHORT $L51 $L65: fstp QWORD PTR [eax-8] $L51: fld QWORD PTR [ebx] fmul QWORD PTR _D$S39 dec edi add ebx, 8 add eax, 8 or edi, edi fadd QWORD PTR [eax-8] jg SHORT $L65 fstp QWORD PTR [eax-8] očigledno je da prvo pomnoži dva broja, uveća sadržaj dva adresna registra za 8, smanji brojač za 1, proveri da li je brojač stigao do 0, sabere dva broja (ovoga puta sa brojem na adresi eax-8), skoči na početak petlje i tek onda prebaci rezultat iz FP registra u memoriju (na adresu eax-8). Izgleda da je ideja bila da se koprocesoru ostavi vremena dok koprocesor izvršava druge instrukcije. Kod Watcom C-a 9.01, na primer, petlja izgleda ovako: L10 fld st(0) fmul qword ptr [edx] fadd qword ptr [eax] inc ebx add edx,00000008H fstp qword ptr [eax] add eax,00000008H L11 cmp ebx,esi jle L10 U realnom modu trenutno je nabrži DETDP3 de.pavlov-a, dobijen pomoću MSC/C++ 8.00 (/AL /Gs /O2 /FPi87), pošto je FDET2 diskfalifikovan jer je radio sa 4bajtnim real-ima. ;) U realnom modu tabela je sledeća: N=200 DET TC 3.1 3.35 sec DETDP TC 3.1 2.41 sec DETDP2 MSC/C++ 8.00 /AL /Gs /O2 /FPi87 2.41 sec DETDP3 Zortec C 3.0 2.41 sec DETDP2 Zortec C 3.0 2.37 sec MSDETDP MSC/C++ 8.00 2.30 sec CDET MSC/C++ 8.00 2.80 sec FDET MS Fortran 5.00 2.74 sec FDET1 MS Fortran 5.00 1.92 sec DETDP3 MSC/C++ 8.00 /AL /Gs /O2 1.87 sec DETDP3 MSC/C++ 8.00 /AL /Gs /O2 /FPi87 1.81 sec
jezici.189 bceklic, -> #177, pedjak
>> za odrzavanje vec kod projekata od 1,000,000 linija koda". Sve >> to cita neko ko pise iskljucivo programe od, recimo, 4-5,000 >> linija koda i od njih sasvim lepo zivi, i sasvim sa pravom >> kaze "e bas me briga" :) > Trenutno radim na programu koji je dostigao 10.000 linija asemblerskog koda i moram priznati da nije ni malo prijatno. U toku rada potrebno je praviti dokumentaciju za sve izradjene module. Svakako da to oduzima dosta vremena i dovodi se u pitanje ako postoji vremensko ogranicenje za izradu programa ali je po meni zaista neophodno. 'Cistoca'i optimizacija koda je vec prica za sebe... POzdrav!
jezici.190 nbatocanin, -> #175, dejanr
> Osim toga, ima stvari koje prosto "plaču" za public > varijablama. Recimo, trenutni username korisnika može da > bude potreban u deset raznih modula, ko da ga svaki čas > prenosi kao parametar? Ovako definišeš promenljive MYNAME, > MYRIGHTS, MYCOLOR i tako dalje, staviš da su PUBLIC, u > svim modulima include-uješ neki fajl u kome piše da su > MYNAME itd memvar promenljive i sve fino radi. Štos sa funkcijom kao zamenom za PUBLIC promenljive je odličan i ja do sada nisam naišao na problem u kome se PUBLIC promenljiva ne može zameniti sa GLOBAL definicijom. Za one koji nisu u toku, kao zamena za PUBLIC promenljivu treba staviti van svih modula deklaraciju GLOBAL MyColor Sada se tekuća vrednost globalnog parametra čita sa MyColor(), a upisuje se sa MyColor("w/n"). Mana je što se troši nešto više memorije i verovatno je malo sporije. Spisak prednosti je daleko veći. Ja sam dodao i opciju PERMANENT koja nalaže da se vrednost čuva/čita iz datoteke, potpuno automatski.
jezici.191 bojt, -> #188, bojt
>> Probao sam (thanks to zormi) Microsoft Fortran PowerStation >> v1.00. Stiže na 3 1.44 diskete i može da se instalira samo preko >> Windows-a, dok je kasnije moguće pokretati kompajler iz DOS-a i >> praviti programe koji mogu da rade samo pod DOS-om. Tja, malo sam danas čeprkao po ovom fortranu i ispostavilo se da on, iako se instalira preko Windows-a i radi pod Windows-ima, pravi programe koji mogu da se izvršavaju samo pod DOS-om. Evo i "objašnjenja" za to: Common Questions and Answers about Microsoft FORTRAN PowerStation Version 1.0a 1. Why does PowerStation run in Windows yet build applications for MS-DOS only? === General ================================================================ 1. Q. The FORTRAN 5.1 development system ran under MS-DOS and built applications for MS-DOS and Windows, and DLLs for Windows. Why does FORTRAN PowerStation run in Windows and build applications for MS-DOS only? A. FORTRAN 5.1 is a 16-bit compiler. There are inherent capacity limitations associated with the 16-bit architecture. In order to allow users to overcome the DOS 640K barrier, we created FORTRAN 5.1 which could generate QuickWin applications, essentially 16-bit applications that use extended memory managed by Microsoft Windows. FORTRAN PowerStation is a 32-bit targeted compiler. Since Windows for DOS is a 16-bit operating system, it would potentially constrain performance for 32-bit applications. 32-bit DOS-extended applications, therefore, was the route of choice. FORTRAN PowerStation is also available for Windows NT. With this product, 32-bit Windows applications and DLLs can be created (for use on Windows NT only). Cvrc... >> Kao rezultat kompajliranja i linkovanja dobija se EXE fajl sa >> ugradjenim DOS-extenderom koji je za više od dva reda >> veličine kraći od EXE fajla koji se BIND opcijom dobija iz, >> na primer, MicroWay NDP Fortrana, što je za svaku pohvalu >> (FDET.EXE je, na primer, dugačak 108K kod MS, a 231K kod NDP >> fortrana). Ni ovo nije tačno. Naime: 5. Q. I compiled and linked my program and it runs fine on the machine where FORTRAN PowerStation is installed but when I take it to another machine it won't run. How can I make this application run on another machine? A. There are two additional files that need to be installed on the machine where you are going to run the FORTRAN application: DOSXMSF.EXE and DOSXNT.386. DOSXMSF.EXE is the actual DOS extender that allows your 32-bit program to run under MS-DOS. DOXSNT.386 is a DPMI device driver that allows your program to run as a 32-bit DOS-extended program under Windows. Both files may be freely distributed (royalty free). You need to install DOSXMSF.EXE either in the same directory as the FORTRAN program or in a directory that is in your DOS PATH environment variable. To install DOSXNT.386, you need the following entry in the SYSTEM.INI file under the [386Enh] section: device=C:\F32\BIN\dosxnt.386 (C:\F32 may be different if you installed PowerStation in a different directory.) Sve u svemu, ne može da radi bez DOSXMSF.EXE (393K) i DOSXNT.386 (9K). ;( Doduše, sreća u nesreći je što: 3. Q. Can I distribute the DOS extender with executables created with FORTRAN PowerStation royalty free? A. Yes. You have the right to distribute the DOS extender files DOSXMSF.EXE and DOSXNT.386 with programs that you create with FORTRAN PowerStation. There is no royalty required. Bar nešto. ;)
jezici.192 dpredovic,
Ovo nije baš prava tema, ali ne znam koja bi bila... Neko veče sam malo "prošetao" BBSovima i na Hellas-u pronašao doslovce BRDO pd i sw C/C++ sors koda i biblioteka. Bilo bi lepo kada bi to neko od ljudi sa malo većim pravom pristupa na Hellas-u mogao da sve to malo da pogleda i prenese. A mogao bi i neko od nadležnih malo da se potrudi (Buuuulaaaajoooo....:))
jezici.193 szinf,
potrebna mi je hitno informacija da li se negde koristi MICRO FOCUS COBOL 2 na UNIX-u unapred hvala, molim vas poruku u mail szinf! Zoran Vignjevic
jezici.194 jkpbvk,
Da li neko ima algoritam za generisanje slucajnih brojeva ? Treba mi ili algoritam ili ako neko ima vec gotov program u FORTRAN-u ali obavezno mora da bude u FORTRAN-u 77 ( novije verzije nevaze, a i imaju naredbu RND ). Unapred HVALA!
jezici.196 aleka,
Hi! Upravo sam naisao na jednu stvar koju ne mogu da razjasnim,a to je ovo: FOR X = 0.1 to 1 step 0.1 PRINT X NEXT X Izlaz: .1 .2 .3 .4 .5 .6 .7 .8000001 .9000001 ^^^^^ Zbog radi cega su ove nule? A interesantno je da se to desava samo pri ovom slucaju! Pozdrav, Mindza. P.S.U nadi da ce vasi programerski mozgovi znati da osvetle ovaj slucaj (Of Course,ako nije restrikcija;))