Android NDK Performance

Diskussion i 'Frågor, support och diskussion' startad av heinrisch, 9 mar 2010.

  1. heinrisch

    heinrisch Teen Droid Medlem

    Blev medlem:
    21 jul 2009
    Inlägg:
    346
    Mottagna gillanden:
    12

    MINA ENHETER

    Tog mig äntligen tiden ikväll för att titta på Android NDK och göra lite test på hur snabbt det går. Är intresserad av optimering och har sysslat en del med C och C++ optimering.

    Detta är vad jag fick fram på min första 2 timmar. Ni får gärna komma med input och tankar :)

    Jag körde ett floating point test på följande kod i C och Java:

    Kod:
     
        public int testJava(int x, int y){
        	float res = 1.234567f;
        	for(int i = x; i < y; ++i){
        		res *= res;
        	}
        	return (int) res;
        }
    
    Kod:
    jint Java_heinrisch_test_performancemdk_MainTest_test( JNIEnv*  env,
                                          jobject  this,
                                          jint     x,
                                          jint     y )
    {
    
    	float res = 1.234567f;
    	int i;
    	for(i = x; i < y; ++i){
    		res *= res;
    	}
        return (int) res;
    }
    Så i princip samma kod i båda språken. Anropade funktionen med 0,1000000.

    Resultatet blev att båda funktionerna retunerade samma svar...

    Men det intressanta då:
    Java tog 2925 ms
    C tog 864 ms

    Ganska stor skillnad :)
     
  2. mannyb

    mannyb Androidpamp Moderator

    Blev medlem:
    14 maj 2009
    Inlägg:
    4 304
    Mottagna gillanden:
    760
    Operatör:
    Project Fi
    Telefon:
    Google Pixel 6 Pro

    MINA ENHETER

    Operatör:
    Project Fi
    Telefon:
    Google Pixel 6 Pro
    ROM:
    Stock
    Telefon 2:
    Google Pixel 4A
    ROM:
    Stock
    Platta:
    Samsung Galaxy Tab S7
    ROM:
    Stock
    Holy crap.

    Och javafolk menar att skillnaden är minimal?
     
  3. sniff

    sniff Youth Droid Medlem

    Blev medlem:
    3 okt 2009
    Inlägg:
    132
    Mottagna gillanden:
    0

    MINA ENHETER

    jag tror mer att javafolk menar att skillnaden är överkomlig och det kan ju grunda sig i att de förmodligen mest bygger applikationer och inte spel.

    edit: intressant test förövrigt.
     
  4. UncleRedz

    UncleRedz Kid Droid Medlem

    Blev medlem:
    7 jun 2009
    Inlägg:
    63
    Mottagna gillanden:
    5

    MINA ENHETER

    Intressant jämförelse. Dock så skulle jag tro att skillnaden skulle minska drastiskt(?) om Dalvik'en hade JIT enablad.

    Det är då som skillnaden mellan Java och C++ blir minimal, på en desktop iallafall. Det hade varit intressant att se samma jämförelse med den där ofärdiga JIT'en som folk lyckats få in i diverse custom firmwares, så att man kan se hur bra JIT'en är redan nu.
     
  5. Kaj

    Kaj Senior Droid Medlem

    Blev medlem:
    12 jun 2009
    Inlägg:
    1 768
    Mottagna gillanden:
    44

    MINA ENHETER

    Låt mig chansa på en sak. Du testar på en device som inte har jitkompilering påslaget (iom att det fortfarande är avstängt by default). Om det är fallet så visar inte testet något om vilken prestanda man har i Java, utan mer om att Dalvik VM fortfarande inte kommit så långt som övriga VMs (tills Jit blir påslaget)

    Även om ditt testfall hade körts på en VM med jitkompilering påslaget så hade jag förväntat mig skillnader. Att göra ett test och mäta prestanda på en enskild beräkning säger inte så mycket om hur hela applikationer går.

    Var t.ex i höstas på JAOO och lyssnade på ett föredrag som en snubbe från Oracle höll (detta var innan Oracle köpte Sun). Han sade att deras C/C++ kod spöade Java när man skrev saker som skulle vara enkeltrådade, men så fort de skrev saker som var gjorda för multitrådning så blev det slagna av Java. Detta pga att trådsäkerhet/multitrådning inte är något som C/C++ är gjort för, och därför tas lås över större områden.

    Java är också bättre på t.ex minneshantering (allokering av objekt i Java är snabbare än i C++):
    Java theory and practice: Urban performance legends, revisited
    "You don't have to search through too many blogs or Slashdot postings to find confidently worded statements like "Garbage collection will never be as efficient as direct memory management." And, in a way, those statements are right -- dynamic memory management is not as fast -- it's often considerably faster. The malloc/free approach deals with blocks of memory one at a time, whereas the garbage collection approach tends to deal with memory management in large batches, yielding more opportunities for optimization (at the cost of some loss in predictability)."

    Det roliga med en bra JIT är dessutom att den optimerar kod dynamiskt i runtime medans en C/C++ kompilator endast kan optimera kod statiskt vid kompilering (statiskt kompilering är något som passar väldigt bra för ditt testprogram iom att det är litet och mycket kan hanteras i register)

    Kort och gott: Man bör inte jämföra exekveringen av en liten metod och sedan dra slutsatser om hur stor skillnaden är mellan applikationer skriva i X och Y.

    Kaj

    Ps. Jag säger inte att Java är snabbare, eller nära C/C++ i hastighet. Säger bara att testet inte visar så mycket, och när du skriver en hel applikation så är det oftast valet av tekniker, algorithmer och hur bra programmerare du har som avgör prestandan.
     
  6. heinrisch

    heinrisch Teen Droid Medlem

    Blev medlem:
    21 jul 2009
    Inlägg:
    346
    Mottagna gillanden:
    12

    MINA ENHETER

    Jag håller med dig i faktiskt allt du skrev. Ska bli intressant att se Dalvik VMs utveckling och hur mycket mer man kan få ut av androidtelefoner.

    Detta test vara bara för att testa en enkel funktion och se om man får något skillnad. Men som det ser ut nu så går det mycket snabbare att köra sin kod i C. Om man tittar på de spel som använder lite mer fysik så är NDKn ett måste.

    Sen är tanken med NDKn att man ska köra liknande saker som det jag gjorde i mitt test. Har man en likande kodsnutt i sitt program så är det fördelaktigt att flytta den till NDKn. Tror inte det kommer bli så populärt att skriva hela program i endast C/C++.

    Det är iaf intressant att se att det finns mycket prestanda kvar att utnyttja
     
  7. Kaj

    Kaj Senior Droid Medlem

    Blev medlem:
    12 jun 2009
    Inlägg:
    1 768
    Mottagna gillanden:
    44

    MINA ENHETER

    ... om man behöver göra beräkningar :)

    För drygt 20 år sedan när man skrev spel till t.ex C64 och Amiga var det väldigt populärt att inte göra beräkningar, utan oftast var det mesta förberäknat och sedan gjorde man uppslagningar mot sina "listor".

    En viktig sak man bör tänka på om man vill ha vissa beräkningar i native, och resten i Java är att anropet Java -> native är relativt dyrt.
     
  8. yayayay

    yayayay Senior Droid Medlem

    Blev medlem:
    27 okt 2009
    Inlägg:
    1 080
    Mottagna gillanden:
    4

    MINA ENHETER

    Min erfarenhet av JIT i custom ROM:s är att det är otroligt instabilt. Stundtals är det mycket snabbare, men ibland kan det sega ner telefonen. Ofta orsakas även slumpmässiga omstarter.
     
  9. Kaj

    Kaj Senior Droid Medlem

    Blev medlem:
    12 jun 2009
    Inlägg:
    1 768
    Mottagna gillanden:
    44

    MINA ENHETER

    Ja, men det är inte så förvånande iom att det än så länge inte är släppt officiellt, och inte skall vara påslaget. Det kommer ju knappast vara så när man äntligen släpper det officiellt
     
  10. UncleRedz

    UncleRedz Kid Droid Medlem

    Blev medlem:
    7 jun 2009
    Inlägg:
    63
    Mottagna gillanden:
    5

    MINA ENHETER

    Hade varit intressant att få lite siffor på vad "mycket snabbare" är.
     
  11. heinrisch

    heinrisch Teen Droid Medlem

    Blev medlem:
    21 jul 2009
    Inlägg:
    346
    Mottagna gillanden:
    12

    MINA ENHETER

    Men ändå i dagsläget så skulle jag säga att förberäkningar är extremt ovanligt och används bara i extremfall. De flesta uträkningarna är "billiga" om man jämnför med lagringskostnad och accesstid.

    Jo det är ju också en sidoeffekt. Men jag tror det inte är så svårt att veta vart man ska dra gränsen, iaf inte i dagsläget, men med en snabbare VM så kanske det blir intressantare.
     
  12. yayayay

    yayayay Senior Droid Medlem

    Blev medlem:
    27 okt 2009
    Inlägg:
    1 080
    Mottagna gillanden:
    4

    MINA ENHETER

    Jag har ingen aning om hur statusen på JIT är, sa bara vad min erfarenhet av det är.
     
  13. Kaj

    Kaj Senior Droid Medlem

    Blev medlem:
    12 jun 2009
    Inlägg:
    1 768
    Mottagna gillanden:
    44

    MINA ENHETER

    Om man har en enhet där man vet att vissa beräkningar är dyra, och om man vet att man kan göra delberäkningar och ha dem lagrade i minnet så bör det vara att föredra (för spel/appar på en mobiltelefon). Med listor menade jag inte filer som skall ligga på disk, utan små datastrukturer som man håller i minne.
     
  14. larsf

    larsf Kid Droid Medlem

    Blev medlem:
    8 jun 2009
    Inlägg:
    56
    Mottagna gillanden:
    16

    MINA ENHETER

    Jag gjorde ett intressant test och anropade metoden tre gånger för att mäta skillnaden då koden redan är kompilerad och klar.

    Time Taken =2604
    Time Taken =135
    Time Taken =107


    Ganska stor skillnad, körde det bara i emulatorn...

    Sättet jag mätte var att modifiera din metod lite
    Kod:
      public int testJava(int x, int y){
        	long timer =System.nanoTime();
        	float res = 1.234567f;
        	for(int i = x; i < y; ++i){
        		res *= res;
        	}
        	  System.out.println("Time Taken =" + String.valueOf((System.nanoTime()-timer )/1000));
        	return (int) res;
        }
    
    Vilket iofs tar lite extra tid då den också skriver på system out men stor skillnad
     
  15. heinrisch

    heinrisch Teen Droid Medlem

    Blev medlem:
    21 jul 2009
    Inlägg:
    346
    Mottagna gillanden:
    12

    MINA ENHETER

    Gör lite mer riktiga tester nu. Kör en 6 sec ljudfil genom FFT för att ådstakomma en pitch shift.

    Med NDKn går det ungefär dubbelt så fort som med ren java kod. Ska se om jag kan slå på lite flaggor i kompilatorn.
     
  16. ellis

    ellis Kid Droid Medlem

    Blev medlem:
    27 maj 2009
    Inlägg:
    51
    Mottagna gillanden:
    0

    MINA ENHETER

    Men ändå rätt aktuellt, då de inte existerar en officiell JIT (som man kan använda utan att flasha om) till Dalvik.

    C/C++ HAR inget inbygt för trådar. Allt berror på vilken platform du jobbar med (t.ex pthreads, OpenMP), och vad dina behov är.

    Det är dock svårare att multi-tråda effektivt i C/C++. Men du har fortförande full kontroll, och kan låsa så mycker eller så lite du vill.

    Java är inte på något sätt "bättre" och eller mer "effektivt". Dåliga programemrare hittar man överallt.

    Igen, beror på underliggande platform och hur allokering görs. Du kan inte allokera minne snabbare än med en malloc(). Därimot, nått Java gör automatisk är en hel del pre-allokering. Då allokeras en del minne i förväg, och när du som programmerare "allokerar", så låser du ett stycke minne från en "memory/object pool".

    Inget som är svårt i C/C++. Som spelprogrammerare så är det mer eller mindre det första optimeringstricket du lär dig, för att de e så sjukligt simpelt.

    Platform. C/C++ är bara ett (två, väldigt relaterade) språk, som implementeras hej vill på alla olika sätt; klassisk offline-kompilering, VM bytecode med eller utan JIT, och t.o.m som ett script-språk.

    Dock i androids fall, så är det tyvär offline-kompilering :(. Inte helt omöjligt att byta ut GCC mot LLVM-GCC dock.





    Ville bara klargöra lite. Annars så har du helt rätt.

    Exemplet är en väldigt liten operation, och görs på så sätt att det inte är verklighetstroget. Men det bevisar iaf att vissa grejer mycket väl KAN vara lättare att skriva effektivt i c/c++.
     
  17. Kaj

    Kaj Senior Droid Medlem

    Blev medlem:
    12 jun 2009
    Inlägg:
    1 768
    Mottagna gillanden:
    44

    MINA ENHETER

    Rätt, men det är på gång, och iom att det är så så visar det bara hur omogen Android är som plattform. Tyckte testet kunde misstolkas, och t.ex tolkas som att Java alltid är avsevärt mycket långsammare än native.

    Nu måste jag erkänna att det var länge sedan jag var C/C++ utvecklare (mer än 10 år sedan). Men jag kommer t.ex inte ihåg sådant som att kompilatorn är tillåten att ändra exekveringsordning på saker för att det skall bli effektivare kod, och att det finns något som är motsvarande volatile. (Mycket har även troligen hänt sedan jag slutade kolla på C och C++)

    Japp, men jag tror inte att Oracle kör med dåliga programmerare när de försöker göra en jämförelse, och skriva en struktur som är liknandes Javas ConcurrentHashMap (vilket Oracle snubben pratade om)

    Jupp, och om man vill göra något liknandes exemplet så är native mycket bättre på även ett annat sätt; footprint och uppstartstid.