SSE memória/regiszter használat időkülönbsége

SSE memória/regiszter használat időkülönbsége
2016-10-20T17:02:54+02:00
2016-10-21T19:35:41+02:00
2022-10-15T22:05:48+02:00
polyJoe
Sziasztok, felmerült a kérdés, nem találom a választ, blablabla...

x86 SSE utasításkészletről kérdezek. Az a szokásos módszer, hogy MOVAPS utasítással beolvassuk az operandusokat, majd a regisztereken dolgozunk, végül MOVAPS utasítással memóriába írjuk az eredményt, valahogy így:
MOVAPS xmm0,var1 MOVAPS xmm1,var2 ADDPS xmm0,xmm1 MOVAPS var3,xmm0

Sehol nem látok ilyen megoldást, pedig rövidebb kód, tehát akár hatékonyabb lehetne:

MOVAPS xmm0,var1 ADDPS xmm0,var2 MOVAPS var3,xmm0
Kérdés: ez valamiért "büntetendő"? (vagyis lassabb lesz?)
Hogy ne titkolóddzak: a belső ciklusomban elfogynak a regiszterek, ezért az invariáns értékeket nem tenném regiszterbe, hanem a fenti módon "röptében" használnám.
Elméleti válaszok és linkek is jöhetnek, tényleg nem találtam rájuk.
Mutasd a teljes hozzászólást!
Vannak ilyen leírások meg táblázatok, amikből lehet okoskodni: http://agner.org/optimize/instruction_tables.pdf - amúgy a site tele van rémes olvasnivalókkal, kicsit később meg ilyet találtam: http://www.agner.org/optimize/microarchitecture.pdf

az invariáns értékeket nem tenném regiszterbe, hanem a fenti módon "röptében" használnám

A mikroarchitektúrás pdf-et pont a cache-elérés sebességére keresve találtam. Ha jól értem, 4 ciklusnak mondja a jelenlegi Intel architektúrákra. Hogy ez neked jó vagy sem, az nyilván az algoritmuson meg az esetleges alternatíváin múlik.
Mutasd a teljes hozzászólást!

  • Kiegészítés: készítettem egy röpke mérést mindkét fenti variációval.
    Tényleg lassabb az alsó kód (~5% több idő). Érti valaki?
    Mutasd a teljes hozzászólást!
  • Vannak ilyen leírások meg táblázatok, amikből lehet okoskodni: http://agner.org/optimize/instruction_tables.pdf - amúgy a site tele van rémes olvasnivalókkal, kicsit később meg ilyet találtam: http://www.agner.org/optimize/microarchitecture.pdf

    az invariáns értékeket nem tenném regiszterbe, hanem a fenti módon "röptében" használnám

    A mikroarchitektúrás pdf-et pont a cache-elérés sebességére keresve találtam. Ha jól értem, 4 ciklusnak mondja a jelenlegi Intel architektúrákra. Hogy ez neked jó vagy sem, az nyilván az algoritmuson meg az esetleges alternatíváin múlik.
    Mutasd a teljes hozzászólást!
  • Hi,

    Ami nem latszik, a kodol, az a loop kezeles:
    A harom utasitasos valtozatnal a 4 elemu instruction queueba bekerul a ciklusvaltozo novelese, amit el is kezd csinalni a proci a mov-al egy idoben.
    A 4 utasitasos valtozatnal pedig a queuban nem lesz benne a ciklus noveles, hanem a queue kovetkezo feltoltesekor benne lesz a ciklus noveles a felteteles ugrassat, amit igy mar a macroop fusion nevu ize segitsegevel kepes a legutolso movval egy idoben vegrehajtani.

    Tehat emiatt tarthat a ket loop ugyanannyi ideig.

    Az
    Mutasd a teljes hozzászólást!
  • A masik dolog, ami szinten bekavarhat, az egy 64 byteos cache line boundary, mert a kicsi instruction queue nem tud egyszerre 2 cache linebol olvasni.

    1 szo, mint 100 az ilyen icipici loopok megirasa kesz muveszet, a fent linkelt Agner Fog Optimization Guide egy pont egy ilyen loop segitsegevel magyarazza 200 oldalon keresztul egy proci mukodeset.

    A tiny loopokat viszont konnyu elkerulni unrollozassal. Es akkor ha pl i7-ed van, akkor  a mem write es a kovetkezo read le tud futni egyszerre. A 4 es harom utasitasos valtozat ekkor, ha az utasitas queue jol van meghajtva, ugyanugy 3 cycle ideig tartana. Tehat i7en egy nagyobb unrollal sztem 2 cycle/ loopot meg kehetne kozeliteni. Olyan procin meg, ami nem ir es olvas egyszerre, ott meg 3 cycle.
    Mutasd a teljes hozzászólást!
  • A loop természetesen nem ebből az egy összeadásból áll, jóval összetettebb, csak szemléltetni próbáltam a lényeget (lehet, hogy nem jól sikerült).
    Tehát: szinte minden SSE utasítás forrás operandusa nem csak regiszter, hanem memória is lehet. Mégis, minden általam talált kód előbb külön beolvassa a memóriából regiszterbe a tartalmat, majd külön elvégzi a műveletet. Ez lassabb kéne legyen, mivel két művelet. De nem az, hanem - úgy tűnik - még kicsit gyorsabb is. Valószínűleg microop szinten a beolvasás+művelet két részre van bontva.

    Az volt az ötletem, hogy ha a konstansokat nem teszem előre regiszterbe, hanem ilyen memóriaoperandusként használom, akkor nem veszítek időt, de nyerek egy regisztert. A jelek szerint nem így van. Jól látom?

    Köszönöm a linkeket. Bár már találkoztam a Fog-féle leírással, de most újra elmélyedek benne.

    Azt jól gondolom, hogy a ciklus-kezelést, meg pointerek léptetését (tehát ami nem sse művelet), azt érdemes "beszórni" az SSE utasítások közé, akkor egyszerre tudja végrehajtani a két egység?
    Mutasd a teljes hozzászólást!
  • Amiatt szoktak kulon mov-ot hasznalni, mert a muveletek 2. operandusa kizarolag csak aligned adat lehet.
    Amugy ha aligned, hasznald az egyszerubbet.

    Barmilyen egymastol fuggesben allo 2 utasitas koze erdemes beszorni mas, azoktol fuggetlen utasitasokat. De ez mar nem olyan bena, mint a pentium 1-nel volt. Rengeteg szabaly van, de sokkal rugalmasabb a scheduler, mert jo esetben 4 utasitast lat elore, csak hat rengeteg szabaly meg penalty van. Ezekrol szol a konyv. :D

    10 eve a procikban 5-6 muveletvegzo van, ezek kepesek egszerre mukodni, 6-7 elemu pipeline-val. -> Add, Mul, Bitwise, Read, Write, Jump. Ezeket is valtogatni kell az utasitas sorrend meghatarozasanal pl.

    En sokszor magamban vigyorgok, amikor látom itt, ott, hogy leírod, hogy nem erdemes asm-al szivni, az algoritmus optimizalasa sokkal eredmenyesebb. Holott valojaban az asm köré kell csavarni az egesz algoritmust. SSE asm nelkul peldaul az L1 cache ki sincs hasznalva, meg a 4x akkora flops/s sem. Ha pedig byte alapu feldolgozasrol van szo, akkor a speedup 16szoros is lehet. De ott vannak a legujabb string kereso utasitasok is, azok egy byte compare networkot hajtanak meg, a hagyomanyos if a kozelebe sem er annak.
    Mutasd a teljes hozzászólást!
  • Már olvasom is a linkeket, persze még nem sok sikerrel. Egy ilyen mondatot találtam: "There is no penalty for using a memory operand in an MMX instruction because the MMX arithmetic unit is one step later in the pipeline than the load unit." Persze ez nem jelent semmit az XMM utasításokra, de lehetséges az analógia. A timing táblák szerint ugyanannyi a latency, csak használja a load portot; vagyis - ha jól értem - akkor fog lassulni, ha az előző/következő utasítás is memóriát olvas.

    Ami a vigyorgásod illeti, teljesen igazad van (talán néha nagyképű kijelentéseket teszek?). Magam is világ életemben asm párti voltam, de C++-ban vagy Delphi-ben sokszázezer soros OOP programot nem fogok assemblyben megírni, és valóban nem javaslom senkinek. Nem véletlen, hogy a fordítóprogramokat és op.rendszereket sem asm-ben írják, csak a leginkább időkritikus részét. Sokat nézegettem a fordítók által gyártott gépi kódot: a Delphi borzalmas, de a GCC dicséretesen szép kódot generál. Persze az asm még jobb.
    Mutasd a teljes hozzászólást!
  • Igen. Egy aligned adatot 1 elokap az elso stage es utana meghet tovabb a muvelet.

    Es amit olvasol az egy nagyon regi iras es felejtsd el az MMX-et, most mar SSE van. 2x olyan hatekony.
    Sokkal inkabb ezt ajanlanam, en ebbol iszonyat sokat tanultam, elotte meg csak annyit tudtam, hogy UV pipe, azt szevaz (tehat semmit) -> http://www.agner.org/optimize/optimizing_assembly.pdf

    "sokszázezer soros OOP programot nem fogok assemblyben megírni" Ki mondta ezt? Az nagy hulyeseg lenne. Kizarolag a belso loopokat erdemes atirni, ha a program a futasanak az ideje joreszet ott tolti.
    Olyan resznek, amivel a program idejen nem tudok huzni legalabb 1.5x annak neki sem allok. Igy hat OOP vezerlokodok, uzleti logika, ini file betoltes, kizarva. Ezeknel a reszeknel pedig mivel a futasidonek csak par szazaleka alatt futnak, az sem erdekel, hogy szép asmot csinal a fordito, vagy nem. Mukodjon a Delphi/MSVC altal generalt kog (a gcc az nekem mar tul sok, lol), azt' majd a 'median filtert' megcsinalom en. Regen osszedobtam egy custom jpeg codec-et: kb. 2500-3000 sor az egesz, ebbol 20-30% az asm es a vegeredmeny kozepes minoseg mellett 20x gyorsabb, mint a Delphibe beepitett cucc, tovabba az enyem a az eredetivel ellentetben thread-safe is. Messze nem 100ezer sorokrol van itt szo, csak parszazhoz, ami viszont fajdalmasan sok tervezest igenyel. (Bele ne koss a Delphi-s jpeg-be, mert ha az olyan rossz lenne, akkor a cegnek 20 evnyi folyamatos *anyazast kene kiallnia, mert azt a jpeg codece rengetegen hasznaljak nap, mint nap, csak eppen nem akartak vele filmet lejatszani, mint en. ;)
    En is csak ott vagyok asm-parti, ahol speedupot lehet vele elerni, mert amugy az egy halal undorito nyelv es mostanaban a regiszterfoglalasokat is inkabb egy automatara bizom, mert de fejjel csinalni azt kimerito es igy 2016-ban elegge ertelmetlen. Viszont valahogy el kell erni a nagyágyút.

    "Delphi borzalmas, de a GCC dicséretesen szép kódot generál"
    Ezt konkret peldakkal ala tudnad tamasztani?
    (En Delphi32 vs MSVC32 kapcsan tudok egyet, ami 30%-al nem szebb (azaz, lassabb, na, de a 64bites forditonal ezt mar korrigaltak :D))
    De inkabb megvarlak elobb teged. 
    Mutasd a teljes hozzászólást!
  • Te sose alszol?

    Most csak egy rövid példát találtam:

    int T[1024]; int sum=0; for (int i=0; i<1024; i++) sum += T[i];
    Értelemszerűen Delphiben ugyanez. RAD Studio XE5:

    Unit1.pas.33: sum:=0; xor eax,eax mov [ebp-$0c],eax Unit1.pas.34: for i := 1 to 1024 do mov [ebp-$08],$00000001 Inc(sum,T[i]); mov eax,[ebp-$08] mov eax,[eax*4+$5c8340] add [ebp-$0c],eax inc dword ptr [ebp-$08] Unit1.pas.34: for i := 1 to 1024 do cmp [ebp-$08],$00000401 jnz $005b477b
    És GCC 5.3.0:

    leal 528(%ecx), %eax leal 4624(%ecx), %edx pxor %xmm0, %xmm0 L1592: 1213:orgframe.cpp **** for (int i=0; i<1024; i++) paddd (%eax), %xmm0 addl $16, %eax cmpl %eax, %edx jne L1592 movdqa %xmm0, %xmm1 psrldq $8, %xmm1 paddd %xmm1, %xmm0 movdqa %xmm0, %xmm1 psrldq $4, %xmm1 paddd %xmm1, %xmm0 movd %xmm0, -188(%ebp)
    De a Delphi célja a gyors fordítás volt (legalábbis a Borland TURBO sorozat azzal reklámozta magát, hogy a világ leggyorsabb fordítója), a GCC meg az optimalizálásra helyezi a hangsúlyt. Ha jól látom.
    Mutasd a teljes hozzászólást!
  • Ott a pont :D

    Az auto-vektorizaciora valahogy nem gondoltam, mert megszoktam, hogy nincs.
    Forditasi idok: Sokkal inkabb a C jellege miatt van szerintem, nem az optimalizalas miatt. A includeok, makrok miatt rohadtsokat kell text-ekkel kinlodni mikozben a Delphi 1 nekifutasra general egy gép által pofonegyszeruen kezelheto valamit minden egyes unitbol.

    Amire amugy en gondoltam, mint sajnalatos kulonbseg az nem ez, mert az egyszeru iskolapeldakra jol megy a dolog, de az eletszagu peldak mar sokkal neccesebbek peldaul most hogyhogynem egy 3x3-as rgb24 median fillterrel szoszolok. Ha az meglesz, akkor annyit lehet tudni, hogy egy emberi SSE implementacio mar van, tehat maga az algoritmus jol vektorizalhato. Kivancsi lennek, mit kezdene vele egy Gcc vector optimizer. Hogy kell irni a kodot c-ben, hogy optimalis sse-t generaljon? Ez szerintem egy rohadnehez feladat, mert ismerni kell a fordito ezen reszet is, ami az SSE processzorokkal ellentetben folyamatosan valtozik. Ez nem szimpatikus benne.

    Te sose alszol?

    Ahogy nezem, azert 2 hsz kozott sikerult megaludnom a 8 orat. 

    Az engem idegesito kulonbseg egy ujabb Delphi meg egy MSVC kozott egyebkent az volt, hogy a float muveleteket a Delphi nem single data SSE utasitasokkal csinalja, ahogy kene, hanem a regi FPU-s utasitasokkal, emiatt a float muveletek 33%-al kovetkezetesen lassabbak.
    Szoval ha sok vektorgeometriat a Delphi itt igencsak hatranyban van, mert minden aprosagot nem fogok megirni asmban, ezt az MSVC meg megteszi.

    Ezt a hibat a 64bites compillernel mar kikuszoboltek, de azert, mert a 64 bites procik mar mind tamogatjak ezeket az egyszerubb sse dolgokat.
    Es itt latszik egy nagy kulonbseg a Delphi es az MSVC kozott:
    - A Delphi 20(?) eve folyamatosan arra torekszik, hogy lehetoseg szerint 1 exe mindent tartalmazzon, ami a futasahoz szukseges, raadasul a nem hasznalt functokat bele sem forditja.
    - Ezzel szemben az MSVC nem akarja, hogy a napjainkban forditott programjai fussanak a regi gepeken, oprendszereken, mert ok OS-el is foglalkoznak es az nekik kulon szivas. Ehelyett egy kozepesen nagy exe melle fel kell rakni egy boszme RTL-t is, ami - MSVC verziotol fuggoen - hemzseg az uj SSE utasitasoktol, ezzel kizarva a legacy felhasznalast. En nem is merek MSVC2013 fole valtani a tobbszori forditassal meg szivjon inkabb a halal, eleg, ha egy build eltart 45sec-ig egy bika cpu-n is (csak ugy izzad a szerencsetlen, lol) :D Meg ha lenne ezentul 2 exe-m, akkor kellene egy harmadik is, amelyik az adott geptol kepessegeitol fuggoen valaszt kozulunk es igy akkor mar el is ertunk napjaink legtrendibb szoftver-ágazatához, a bloatware-hez. 
    Mutasd a teljes hozzászólást!
  • Akkor a GCC nem is olyan rossz Amúgy miért nem próbálod ki? Nekem az egyetlen kifogásom a sebessége volt, de ezt ezek szerint jobb, ha visszaszívom, ráadásul egy -j opcióval annyi példányban fut párhuzamosan, ahány mag van a gépben (semmi más nem is tud futni olyankor ), a teljesítménye innen nézve nem is rossz.
    Az auto-vektorizálásról ld. itt, nem olyan bonyi. Annyit csaltam a fentebbi C++ kódban, hogy a T[] tömböt 16 bájtra illesztettem, mert különben még beszúrt a ciklus elé egy durva hókuszpókuszt.
    Ja és alapból két DLL-t használ, de -static opcióval befordítható az exebe, és akkor önjáró.

    Az MSVC milyen kódot generál? Nekem viszont arról nincs tapasztalatom.
    Mutasd a teljes hozzászólást!
  • Fura az a Pascal (Delphi) kód, elég ősinek látszó cikkben (Dr.Bob's Delphi Clinic: Dr.Bob's Delphi Efficiency Optimisation including PDF to excel ) is azt írják, hogy

    Heavily used variables and parameters will automatically be placed into registers, reducing the number of machine instructions required to load, access and store a variable. This results in much faster code since there is no need to load variables from memory into registers. This optimisation is done automatically by the compiler with no need to specify that certain variables or parameters should be placed in registers. The compiler also automatically performs variable "lifetime analysis" in order to be able to re-use registers. For example, if a variable I is used exclusively in one section of code and a variable J is used exclusively in later section of code, the compiler will use a single register for both I and J.

    Na, ez totálisan nem történik meg a kódban, hiszen az i-t is, meg a sum-ot is folyamatosan frissen tartja a memóriában. Biztos, hogy nem tiltottad le az optimalizálásokat? Esetleg debug fordítás mellékhatása?
    Mutasd a teljes hozzászólást!
  • Megnézem.
    Mutasd a teljes hozzászólást!
  • Megnéztem, bekapcsoltam az optimalizálást (egyetlen kapcsolót találtam on/off - ez nincs "túlszofisztikálva"!). A kód ugyanaz maradt.
    Mutasd a teljes hozzászólást!
  • Simán lehet, hogy a cikk adott részlete csak "wishful thinking" volt.
    A FreePascal amúgy lehet, hogy jobb kódot fordítana ebből a konkrét ciklusból, legalábbis ftp://ftp.freepascal.org/pub/fpc/docs-pdf/chart.pdf még MMX-et is említ.
    Mutasd a teljes hozzászólást!
  • Kicsit kozelebbrol megneztem en is:

    Igen, be lett nezve az optimize checkbox :D

    3 valtozat: Delphi stack, Delphi dataseg, Sajat

    Mindharom 0.510ms alatt fut le.
    Iteraciok szama: 1M*1024
    A gepem 4GHz-s
    Egy loop ideje = 4GHz/1024M = kb. 4 cycle.

    Ez alá pedig egy loopnal ezen az AMD Bulldozeren sztem keptelenseg lejjebb menni. Az Agner Fog is asszem 4 orajeles loopot mutat be egy  = DAXPY (masneven MAC) muvelet segitsegevel, ami velunk ellentetben még szoroz is :D

    Tehat jojjon a 3 asm loop:

    Delphi, static T[]
    add ecx,[eax]
    add eax,$04
    dec edx
    jnz $0041a320

    Delphi, T[] on stack
    add ecx,[eax]
    add eax,$04
    dec edx
    jnz $0041a340

    Sajat:
    add eax,[edx+ecx*4]
    dec ecx
    jnz @loop

    Vegezetul ket erdekesseg:
    Delphi, optimize nelkul, ez egeszen pontosan 5x lassabb, mint a fentiek :D:
    mov eax,[ebp-$08]
    mov eax,[eax*4+$423ed8]
    add [ebp-$0c],eax
    inc dword ptr [ebp-$08]
    cmp [ebp-$08],$00000400
    jnz $0041a360

    program SmallLoopTest; {$APPTYPE CONSOLE} uses System.SysUtils, windows; function test1:integer; var i, sum:integer; var T:array[0..1023]of integer; begin sum:=0; for i:=0 to 1023 do inc(sum, T[i]); result:=sum; end; var T:array[0..1023]of integer; function test2:integer; var i, sum:integer; begin sum:=0; for i:=0 to 1023 do inc(sum, T[i]); result:=sum; end; function test3:integer; asm lea edx,T[-4] //T[-1] xor eax,eax //sum mov ecx,1024 //cnt (decremented) @loop: add eax,[edx+ecx*4] dec ecx jnz @loop end; var i, batch:Integer; t0,t1,tf:int64; begin for i:=0 to high(t)do t[i]:=i; //523776 writeln(test1,' ',test2,' ',test3); for batch:=0 to 3 do begin QueryPerformanceCounter(t0); for i:=0 to 1000000 do test1; QueryPerformanceCounter(t1); QueryPerformanceFrequency(tf); writeln(format('%10.3f',[(t1-t0)/tf])); end; readln; end.
    Mutasd a teljes hozzászólást!
  • Akkor a GCC nem is olyan rossz Amúgy miért nem próbálod ki? Nekem az egyetlen kifogásom a sebessége volt, de ezt ezek szerint jobb, ha visszaszívom, ráadásul egy -j opcióval annyi példányban fut párhuzamosan, ahány mag van a gépben (semmi más nem is tud futni olyankor ), a teljesítménye innen nézve nem is rossz.

    Nekem is az egyetlen kifogasom a sebessege. Egyszeruen nem tudok ugy haladni, ha minden 2. sor utan nem nyomhatok egy F9-et es 0.2 masodperc mulva nem all ott a debugger a tesztelendo breakpointon, vagy teszemazt az eppen kiserletezes alatt allo dolgot nem nezhetem meg vizualisan (sokat rajzoltatok a geppel, hogy atlassam a dolgokat :D, az en agyam ehhez keves). Raadasul mindezt teszi Optimizalt koddal!

    Emiatt elnezem neki, hogy nincs auto vektorization. Azt mar kevesbe, hogy a sima float muveleteket is csak a 64bites compiler csinalja jol, de ezt mar leirtam, a delphi altal kiadott 32bites exe szeret mindenen elindulni es ezen ugy nez ki, nem akarnak valtoztatni.

    Az egy kulon tema lehetne, hogy miert is odzkodom a 64bit-tol de pont most neztem meg, hogy mit csinal egy ilyen mikro-looppal ez tovabbra is allnak az eloiteleteim sajnos: A 64bites Delphi altal forditott valtozat nem 4, hanem 5 cycle alatt megy. Egyszeruen azert, mert a 64bit miatt mar tul le van terhelve a cpu az extra prefixektol: Hiaba lett 2x annyi, 2x akkora standard regiszter, de az eleresuk miatt viszont nem lehet azert tulzasba vinni a hasznalatukat.

    Win32, Delphi 512ms 0308 add ecx,[eax] 83C004 add eax,$04 4A dec edx 75F8 jnz $0041a340 //8byte code Win64 Delphi 775ms (lemaradt) inc r8 42030C82 add ecx,[rdx+r8*4] 83C001 add eax,$01 81F800040000 cmp eax,$00000400 75E7 jnz test2 + $6 //15 byte code, lots of prefixes //Update!!!! Itt kimaradt az a resz, ami a r8-ban levo indexet noveli, //Update!!!! Eskuszom mar en is azt mondom, hogy csunya a delphi kod, csak en ezt erre a 64 bitesre ertem o.O Win64, Sajat asm, 512ms (pont, mint a 32bites delphi, vagy a sajat ott) 6703048A add eax,[edx+ecx*4] FFC9 dec ecx 75F8 jnz test3 + $E //8 byte code
    Mutasd a teljes hozzászólást!
  • A világ sokkal érdekesebb, mint hinnénk
    Megesküdtem volna, hogy a Te kódod a leggyorsabb (mármint unroll nélkül). De nem, kis agyalás után ez nekem jelentősen gyorsabb:

    function test4:integer; asm lea edx,T[-4] xor eax,eax //sum mov ecx,4*1024 //cnt (decremented) @loop: add eax,[ecx+edx] sub ecx,4 jnz @loop end;
    Ráadásul mindegy, hogy az edx-et használom, vagy a tömbcímet berakom a ciklusba, úgy tűnik az gyorsít, hogy nincs *4 eltolás.

    Ja és igazad van a Delphi gyors fordításával, viszont a GCC asszem az egész ciklust kihagyja, mivel nincs szükség az eredményére. Most nem tudom kipróbálni, de tipikusan így szokott lenni.
    Mutasd a teljes hozzászólást!
  • test1..test4 nalam rendre 4 cycle.

    Neked a test4-et akkor jobban szereti a te processzorod. Mi a helyzet a test1..3-al. Szamolj inkabb te is cycle-ben, ha mar kis loopok.

    Amugy olyan ez, mint a voodoo mágia, nem szeretem, hogy nem tudom, hogy mit csinalok, haha. Viszont nagy loopokkal sokkal egyszerubb kihozni a maximumot.
    Mutasd a teljes hozzászólást!
  • Igen, ez így van!
    Ez most egy 3,4GHz Pentium-D (Presler) gép, ez van kéznél. Ki fogom próbálni másokon is.
    test1..3 rendre 0,730 a test4 490!!!

    És kipróbáltam Lazarus-t is, ugyanezek az eredmények, bármit kapcsolgatok (pedig ott van P4 processzor opció is, meg többféle optimalizálás), akkor is ugyanazt fordítja, semmi XMM. Vagy elrontok valamit?
    Mutasd a teljes hozzászólást!
  • Bocs, rosszul szamoltam!

    4GHz/(1024M/0.512sec) = 2 cycle  (elfelejtettem osztani a futasi idovel, ami veletlenul tokre kerek lett.
    Tehat:
    AMD FX8350 = 2Cycle
    3.4GHz Presler = 3.4/(1024/0.730) = 2.4 cycle  (test 4 = 1.6cycle <-Szerintem ez tutira nem jol szamol :D)

    Ellenoriznem, hogy jol szamol-e (program.begin utan ott az a writeln(test1,' ',.....).

    Nalam valahogy kisertetiesen jol kijott a 2 cycle :D
    Mutasd a teljes hozzászólást!
  • Azért ennyire óvatos vagyok jól számol. És következetes az idő, és ugyanannyi Lazarus és Delphi alól is.

    Kipróbáltam egy másik gépen is: Core i5 2,6GHz. Itt a két Pascal kód 0,900 és a Te kódod egyformán az enyémmel 0,600. (de ez így se kerek ciklus)

    Szóval ez tényleg voodoo !
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd