Php + js - java - c# - c++ kód és sebesség

Php + js - java - c# - c++ kód és sebesség
2014-03-06T08:24:10+01:00
2014-03-10T10:00:18+01:00
2022-10-22T17:45:35+02:00
  • Ohh, köszönöm.
    Mutasd a teljes hozzászólást!
  • Meglestem, az eredmény nem véletlen. Azért gyorsabb, mert kevesebb műveletet végez :)

    -O2-vel az alábbit csinálja ciklusonként:
    5db 3.3-as fadd
    +1db 16.5 fadd
    tehát a ret2-es változódat kioptimalizálja és egyszer egybe adja hozzá az értékét a korábbi összedásokhoz.

    -O2 -ffast-math:
    Teljesen kioptimalizál mindent, ciklusonként 1 darab összeadás, ahol 33.0-át add hozzá..
    Azaz 10-ed annyi művelet
    Mutasd a teljes hozzászólást!
  • Nézd meg, hogy mire fodrul :)

    gdb programnev disass main
    Mutasd a teljes hozzászólást!
  • Hmm, a te kódod -O2;-ffast-math -al 121ms nálam.

    Ez viszont -O2-vel 59ms, -O2;-ffast-math -al 10ms:

    #include <stdio.h> #include <sys/time.h> #include <iostream> #define Log(m) std::cout << m << std::endl; #define TM_START struct timeval tv;unsigned long time_stamp; unsigned long t; #define TM_POINT_START gettimeofday(&tv,NULL);time_stamp = 1000000 * tv.tv_sec + tv.tv_usec; #define TM_POINT_END(s) gettimeofday(&tv,NULL);t =1000000 * tv.tv_sec + tv.tv_usec;Log(s << ((t - time_stamp)/1000) << "msec"); double add1(double a, double b) {return a+b;} int main(int argc, char **argv) { TM_START; double ret = 0.0; double ret2 = 0.0; TM_POINT_START for(int i = 0;i<100000000;i+=10) { ret2 = 0.0; ret += add1(1.1, 2.2); ret2 += add1(1.1, 2.2); ret += add1(1.1, 2.2); ret2 += add1(1.1, 2.2); ret += add1(1.1, 2.2); ret2 += add1(1.1, 2.2); ret += add1(1.1, 2.2); ret2 += add1(1.1, 2.2); ret += add1(1.1, 2.2); ret2 += add1(1.1, 2.2); ret +=ret2; } printf("res: %f\n", ret); TM_POINT_END("[double add, unroll, fuggoseg]"); return 0; }


    Kíváncsi lennék rá, hogy miért ennyivel gyorsabb.
    Mutasd a teljes hozzászólást!
  • Na, erre szokták mondani, hogy az a különbség az elmélet meg a gyakorlat között, hogy bár elméletben a gyakorlat és az elmélet is ugyanaz, a gyakorlatban viszont nem feltétlenül. A legtöbb programozónak ez az első Hello world-nél bonyolultabb programja után leesik. Mondom: a legtöbbnek.
    Mutasd a teljes hozzászólást!
  • mert kelL
    Mutasd a teljes hozzászólást!
  • Működik a 2xeres speedup :)
    281ms a 10^9-es (azaz az egy nagyságrenddel nagyobb adaton).

    de így már a kód nem igazán hasonlít az eredeti kódra. Magától nem tudja normálisan unrollozni..

    A fordítónak abból állt az unroll, hogy az
    addpd xmm0,xmm1
    utasítást 8szor vette a ciluson bellülre, a ciklusszámot pedig a 8adára vette.
    -funroll-loops kapcsoló eredményezte ezt, de kézzel kicsit módosítva sem segített.
    Ez így természetesen nem változtatott különösebben a futásidőn..

    A jelentős átírás után generált kód:

    0x00401cee <+38>: xorpd xmm1,xmm1 0x00401cf2 <+42>: movapd xmm4,xmm1 0x00401cf6 <+46>: movapd xmm3,xmm1 0x00401cfa <+50>: movapd xmm2,xmm1 0x00401cfe <+54>: movapd xmm0,XMMWORD PTR ds:0x403090 0x00401d06 <+62>: xchg ax,ax 0x00401d08 <+64>: addpd xmm2,xmm0 0x00401d0c <+68>: addpd xmm3,xmm0 0x00401d10 <+72>: addpd xmm4,xmm0 0x00401d14 <+76>: addpd xmm1,xmm0 0x00401d18 <+80>: dec eax 0x00401d19 <+81>: jne 0x401d08 <main+64> 0x00401d1b <+83>: addpd xmm1,xmm4 0x00401d1f <+87>: addpd xmm1,xmm3 0x00401d23 <+91>: addpd xmm1,xmm2 0x00401d27 <+95>: movapd XMMWORD PTR [ebp-0x28],xmm1 0x00401d2c <+100>: fld QWORD PTR [ebp-0x20] 0x00401d2f <+103>: fadd QWORD PTR [ebp-0x28] 0x00401d32 <+106>: fstp QWORD PTR [ebp-0x38]
    most bemásoltam az eredmény kicsomagolásának a menetét is..
    (Ez a nem párhuzamosított verzió)
    Mutasd a teljes hozzászólást!
  • Nekem az agyamra megy ez a szellemi onanizálás a sebességgel

    Aki tudja mit csinálnak az egyes környezetek programkódjai (hogyan lesz futó program a végén) az minden esetben előre tudja a válaszokat.

    Minden ettől eltérő eredmény:
    -- tesztelési hiba vagy
    -- teszteszközök implementációjának hibája vagy
    -- algoritmizálási hiba.

    Ennyi!

    A valósággal lehet szembemenni, de nem érdemes.
    Minden környezethez, nyelvhez (a megvalósítási módja okán) megadatott, hogy hogyan hatékony, mire akalmas és célszerű.

    Ez pedig az elmélet ismeretében egyértelmű (márakinek).

    Ha meg valahol nem az elméletnek megfelelő eredmény jön ki (persze nem az információk összességének egy szelete!), akkor ott valaki valamilyen hibát vét.
    Jó esetben figyelmetlen, rossz esetben elvakult.
    Mutasd a teljes hozzászólást!
  • nem a memset a lényeg
    hanem pontosan az, hogy a Garbage Collector-nak iszonyatos melót adok

    Ha megnézed, a példaprogram legvégén direkt lekérdezem, hogy a Gen2 gyűjtés hányszor futott le.

    Normál programműködés mellett a Gen2 rettentően ritka kell, hogy legyen (a legjobb az lenne, ha nem is volna).
    Ezzel a kis progival nekem 312x gyűjtés történt (nyílván ennél jóval több lesz, csak az már a lekérdezés után történik meg), az pedig iszonyatos lassulást tud okozni.
    Még Concurent/Background GC mellett is.

    Egy ideje nem olvastam ezirányban cikkeket, de tapasztalatból mondom, minél többször fut len a Gen2 gyűjtés, annál nagyobb lag-ok keletkeznek a rendszeredben.
    Párezer Gen2 után már drasztikusan láthatón kifagy a rendszer, amíg a gyűjtés történik.
    Mutasd a teljes hozzászólást!
  • Nincs valami beepitett fillchar() vagy memset() ezekben? ;)
    Meg 100000x alloc/free-vel is inkabb csak a memory managert izzasztod, nem a fordito kepessegeit mered.
    Mutasd a teljes hozzászólást!
  • Ezt szepen vektorizalta  (Az a rész lemaradt, amikor a 2 double-t a vegen osszeadja, a vegso eredmeny miatt. Illetve amikor a paratlan iteraciot is kezeli(na jo, azt a konstans iteracioszam miatt kioptolja))

    Az idôk alapjan is nagyon szepen lejon, a vektorizalt es a vektorizalatlan belso loop is ugyanannyi orajelet eszik (sztem 3 clk). Ezen egy 4-8x unroll még tudna segiteni, mert a double.add-nak 3 a latency-je, de ha fuggetlen adaton dolgozik, akkor orajelenkent megbir 1 osszeadast.

    @1:
    addpd x0, x7  ;x7=3.3
    addpd x1, x7
    addpd x2, x7
    addpd x3, x7
    dec eax
    jne @1

    Ez mondjuk olyan 6 clk, de 4x tobb adatra, szoval lehetne a 4x unrolltol 2x speedup.

    Adj rá 4x unrollt pls! Kivancsi vagyok :D
    Mutasd a teljes hozzászólást!
  • Nem c#-ból indítva! release mappában lévő executable command prompt-ból..
    Mutasd a teljes hozzászólást!
  • Alap C# változat (release természetesen) 676ms a gépemen

    lehet, hogy  csak elsiklottatok a kérdés felett
    amikor c# release-t indítod, azt avisual studióból csinálod?

    közben írtam egy kis ".Net killer like" programot

    class Program { const int maxSize = 100000; const int maxIteration = 10000; static public byte[] Duck() { var b = new byte[maxSize]; for (var i = 0; i < maxSize; i++) { b = 255; } return b; } static void Main(string[] args) { byte[] _byteArray; Stopwatch sw = new Stopwatch(); sw.Start(); for (var i = 0; i < maxIteration; i++) { _byteArray = Duck(); for (var j = 0; j < maxSize; j++) { _byteArray[j] = 0; } } sw.Stop(); var gen0 = GC.CollectionCount(0); var gen1 = GC.CollectionCount(1); var gen2 = GC.CollectionCount(2); Console.WriteLine(sw.ElapsedMilliseconds); Console.WriteLine("Gen0:{0} -- Gen1:{1} -- Gen2:{2}", gen0, gen1, gen2); Console.ReadLine(); } }

    release: 1100 ms


    javascriptben - firefox - 13000 ms

    var maxSize = 100000; var maxIteration = 10000; function Duck() { var b = new Array(); for (var i = 0; i < maxSize; i++) { b
    = 255; } return b; } var start = new Date().getTime(); for (var i = 0; i < maxIteration; i++) { _byteArray = Duck(); for (var j = 0; j < maxSize; j++) { _byteArray[j] = 0; } } var end = new Date().getTime(); var time = end - start; alert('Execution time: ' + time);


    amúgy az első progit megírtam typescript
    amit fordított JS az kb 2x gyorsabb stabilan firefoxban
    Mutasd a teljes hozzászólást!
  • Belelestem, hogy mivé fordul.
    megj:
    Floating Point to Hex Converter
    0x400a666666666667 = 3.3
    Tehát a belső 2.2 + 1.1-et úgy ahogy van már fordításidőben kiszámolta

    A korábbiakban leírtaknak megfelelően:

    -sima O2-es verzió:

    0x00401ce9 <+33>: mov eax,0x5f5e100 0x00401cee <+38>: fldz 0x00401cf0 <+40>: fld QWORD PTR ds:0x403080 0x00401cf6 <+46>: xchg ax,ax 0x00401cf8 <+48>: fadd st(1),st 0x00401cfa <+50>: dec eax 0x00401cfb <+51>: jne 0x401cf8 <main+48> Contents of section .rdata: 403080 67666666 66660a40 gfffff.@

    -vectorized verzió:

    0x00401ce9 <+33>: movapd xmm1,XMMWORD PTR ds:0x403090 0x00401cf1 <+41>: xor eax,eax 0x00401cf3 <+43>: xorpd xmm0,xmm0 0x00401cf7 <+47>: nop 0x00401cf8 <+48>: addpd xmm0,xmm1 0x00401cfc <+52>: inc eax 0x00401cfd <+53>: cmp eax,0x2faf080 0x00401d02 <+58>: jne 0x401cf8 <main+48> Contents of section .rdata: 403090 67666666 66660a40 67666666 66660a40 gfffff.@gfffff.@
    Parallel for-os verziókat fölösleges bemásolni azt hiszem..
    Alap C# változat (release természetesen) 676ms a gépemen
    Mutasd a teljes hozzászólást!
  • freepascal: 26ms
    Mutasd a teljes hozzászólást!
  • Hú de régi gépem van.
    Beraktam firefox/firebug konzolba. Először összeomlott a firefox, másodszor folyamatosan felteszi a kérdést, hogy folytatni akarom-e, mert végtelen ciklust érzékel és végül 185098 a végeredmény
    Mutasd a teljes hozzászólást!
  • +10 fillér kevésbé elterjedt processzoron (powerpc g4 (2005), stable debian, rövidített ciklus)

    g++ -O2: 3.7 ms
    mono: 25 ms
    g++: 43 ms
    java: 113 ms
    midori: 530 ms
    opera: 685 ms
    firefox: 1785 ms

    Illetve vegyük észre, hogy a példa elég JIT barát. Se komolyabb osztályok,
    öröklődés, sablonok, UI, folyamatok, I/O ...

    Vajon miért van az, hogy a firefox-ot, és a chrome-ot nem js-ben,
    az openjdk-t nem (csak) java-ban,
    a mono-t nem tisztán C#-ban írják?
    Mutasd a teljes hozzászólást!
  • Chrome: Verzió: 33.0.1750.146

    <html> <head> <script> function Add(a,b) { return a+b; } var start = new Date().getTime(); for(i=0; i<100000000; i++) { var c = Add(1.1,2.2); } var end = new Date().getTime(); var time = end - start; alert('Execution time: ' + time); </script> </head> <body> </body> </html>
    460-480 ms viszonyítási alapként

    Nincs kedvem C#-ban és egyébb nyelvekre lekódolni (JavaScript-hez nem értek, Java-ban sem csináltam még többet helloWorld-nél), de nyílván ott is lekódolhatóak párhuzamosítva biztos, de még talán vectorizációt is engedélyezve. Kíváncsi lennék az összes eredményére, egymásmellé állítva :)
    Mutasd a teljes hozzászólást!
  • Hogy miket fordított, azt sajnos még lusta voltam megnézni, de szerintem az eredmények magukért beszélnek:
    GCC 4.7.2-t használtam:

    #include <iostream> #include <chrono> using namespace std; using namespace chrono; double Add(double lhs, double rhs) { return lhs + rhs; } int main() { double c = 0.0f; auto start = high_resolution_clock::now(); #pragma omp parallel for reduction(+:c) for(size_t i = 0; i < 100000000; ++i) { c += Add(1.1, 2.2); } auto end = high_resolution_clock::now(); cout<<"Execution time: " + 3<<duration_cast<milliseconds>(end - start).count()<<"ms"<<endl; cout<<c<<endl; return 0; }
    Nekem ez a kód:
    g++ -std=c++11 -Wall -Wextra -O2 -ffast-math
    218ms

    vektorizációval, ami simán sikerült neki:
    g++ -std=c++11 -Wall -Wextra -O2 -ftree-vectorize -msse2 -ftree-vectorizer-verbose=5 -ffast-math
    109ms, tehát egyszerre 2 összeadás az 1 helyett

    párhuzamosítva, de vektorizáció nélkül:
    g++ -std=c++11 -Wall -Wextra -O2 -fopenmp
    109ms nem meglepő módon, mivel 2 magos a gépem :)

    párhuzamosítás + vektorizáció:
    g++ -std=c++11 -Wall -Wextra -O2 -ftree-vectorize -msse2 -ftree-vectorizer-verbose=5 -ffast-math -fopenmp
    62ms :) -> 2mag, mindegyiken vektorizálva
    Mutasd a teljes hozzászólást!
  • 10ms 10^8 műveletre gyanús nekem. Multithreading és vectorization nélkül!! Ehhez  legalább 10GHz-en kéne pörögnie a dolgoknak, ha nem optimalizálta ki a nehezét :)

    10ms => 10^8 művelet
    1000ms = 1s => 10^10művelet = 10 GHz
    Mutasd a teljes hozzászólást!
  • Hogy futtattad a lefordított kódot?
    Három gépen is kipróbáltam, és nem sikerült 70 fölé vinnem, kivéve ha VS-ből indítom F5-tel. Ebben az esetbe csatolódik a debug (még a release-hez is). CTRL-F5-tel normálisan megy.
    Mutasd a teljes hozzászólást!
  • -O2 van (mindig), vektorizálás nem volt. 
    -O2+-ffast-math  -al (10^8-s ciklus) az unrollolt lemegy 10msec-re.

    De összegben is van eltérés:
    -O2, for() res += add(a,b); -> 3300000000.028741
    -O2, unroll:  ->329999999.999950
    -O2, unroll, -ffast-math: ->330000000.000000
    -O3 (meg sse kapcsolókkal) jött ki  3300000044.709906 is.

    helyes: add(1.1, 2.2) -> 330000000.000000
    Mutasd a teljes hozzászólást!
  • a node.js az megfelelő erre a célra vagy mindenképp érdemes kiszedni az svn-ből és buildelni?
    csak azért kérdezem, mert a node nekem stabilan 330ms-t dob
    Mutasd a teljes hozzászólást!
  • És akkor mi van, ha c++ megírjuk SIMD-el, vagy auto-vectorizáltatunk vele. Kapásból egy 3-4es gyorsulás várható :)Bár valószínűleg a többi nyelv is támogatja..

    alap: c++ ~108ms

    -O2 az be van kapcsolva legalább, vagy 0 optimalizáció?
    Mutasd a teljes hozzászólást!
  • Nekem firefox is ugyanezt tolja, sőt stabilan inkább 1msec-el gyorsabb.

    Viszont nekem a csak 10000000 -ig megy a ciklusom, a te peldádban 10x több van :)
    100000000 -esetén:
    alap: c++ ~108ms, js: ~110ms

    unroll, függőség csökkentés:
    C++60ms, js 60-65ms között random.

    (3 éves i3 procin)
    Mutasd a teljes hozzászólást!
  • otthon lesz chrome, megnézem ott is (bár az w8, nem tudom jelent-e majd valamit)
    Mutasd a teljes hozzászólást!
  • fura
    ilyesmit csak akkor művelhetne, ha Studioból indul
    ezt a v8-at viszont megnézem, ha tényleg ilyen gyors
    Mutasd a teljes hozzászólást!
  • Release.
    Mutasd a teljes hozzászólást!
  • F5+debug?
    Mutasd a teljes hozzászólást!
  • chrome-n az alap nálam olyan 20msec-ig fut, unroll, meg függőség csökkentéssel ez lemegy kb 10msec-re, viszont ha rátenyerelek a frissítésre, akkor leviszi 7-9msec-re.

    Ami majdnem megegyezik C++ -os sebességgel, ami persze már első futtatásra is 6-7msec-t ad.

    Kis pihi után egy frissítés, és megint 10msec a chrome-ban.

    Érdekes ez a menet közbeni optimalizálás amit vivo linkelt.
    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