Ugrás a főmenüre.
Minden más 2011.05.10.

Low-level iOS, hogyan lehetne gyorsabb?

A mai Meetup-on tartott előadásommal kapcsolatos fejlesztői infók, kódokkal.

  • Látványos eredmény megfelelő szálkezeléssel, UIKit frissítés optimalizációval és ARM Assembly-vel érhető el.
  • A szoftver a király: sokkal több erőforrás takarítható meg jó kóddal, mint mondjuk egy új szuper GHz kétmagos CPU-val. 
  • Ha egyébként rendben van a kód. Például használjunk "tiszta" C-t Objective-C objektumok helyett, ha lehetséges.

Hogyan mérjük a terhelést?

  • Instruments: elsősorban RAM, szivárgás és Core Animation mérésre. CPU-hoz nem jó, abból eleve sokat eszik, az apró különbségek nem látszanak.
  • Csak a teljes, rendszerszintű idle idő számít. Mérése kódból megoldható (csatoltam).
  • A felhasználó a teljes rendszer terhelését érzi, nem az alkalmazásunkét. Könnyű "átvinni" a terhelést a saját kódból az OS-hez (user % -> sys %), de ez nem szabadít fel semmit.

Ökölszabály

25-30% szabad CPU mindig kell, különben "akadozik" az élmény.

NSRunLoop

  • A main thread NSRunLoop-ja fontos. Többek között ez fogadja az érintés és egyéb felhasználói eseményeket.
  • Ha nincs 25-30% szabad CPU, akkor későn fut, későn érkeznek az események - akad.
  • Main thread/main run loop blokkolására ügyelni, események lehető leggyorsabb feldolgozása, külön thread, ha kell.

Szálkezelés

  • Fontos a megfelelő prioritás, időszelet (mennyi CPU-t használhat adott időtartam alatt) és stratégia (FIFO, RR, OTHER) beállítása.
  • Nincs rá jó SDK megoldás (NSThread setThreadPriority nem megfelelő), hibrid mach/pthread kód kell. Csatoltam.
  • Ezzel lehetséges olyan szál futtatása, ami csak a "szabadidőben" fut (idle CPU).

UIKit

  • Egy UIKit objektum (pl. UIButton) módosítása "költséges", az UIKit a legtöbb esetben blokkol, amíg be nem fejezte a grafikát.
  • Összegyűjteni a módosításokat (pl. UIButton.highlighted), és végrehajtani később, nem a touch event kezelésekor.
  • CADisplayLink! Ezzel lehet időzíteni a frissítéseket.
  • Az iPhone utálja az átlátszóságot, alpha csatornákat, belassul.
  • A legtöbb objektum átlátszatlan legyen, opaque-ra Interface Builder-ben pipa (igen, végig kell kattintgatni az összeset).
  • Még így se "halmozzuk egymásra" az objektumokat.
  • Ha opaque egy objektum, de alpha-s PNG kép van benne, akkor átlátszó lesz így is...
  • Irtsuk ki az alpha csatornát a felhasznált képeknél, ha lehet.
  • A szövegek, UILabel módosítása költséges. Saját drawRect metódus és [self.text drawInRect: vagy CGContextShowTextAtPointsokat segít.
  • A saját drawRect metódusok sokszor gyorsabbak.
  • Instruments - Core Animation - Flash Updated Regions. Meg fogsz lepődni.

Thumb mód

  • ARM CPU-k, kétféle futási mód: Thumb és ARM.
  • Thumb mód: kisebb kód és más utasításkészlet, ezért kisebb memória sávszél igény - gyorsabb futás, régi eszközökön (nem iPhone).
  • Nem tud lebegőpontos számítást, ilyenkor a fordító átkapcsolja a CPU-t ARM módba, aztán pedig vissza. Ez lassú.
  • iOS fordító: a Thumb mód alapértelmezett, kapcsoljuk ki. Iterációknál sokat számíthat.

Iterációk optimalizálása - ha az Assembly "túl sok" lenne

  • Nézzük meg, hogy a compiler milyen kódot gyárt.
  • Elé és mögé inline asm sorok ( __asm__ volatile ("#innen"); ), majd pedig Build - Show Assembly Code.
  • Próba: "register" kulcsszó néhány fontos változónál, mennyit változik az Assembly kód. Nem kell annyit töltögetni a memóriából.
  • A compiler nem mindig jó a regiszterek hatékony elosztásában, csak néhányat használ.
  • Egyszeres lebegőpontos számokat érdemes használni (sima, 32-bites float), hogy a compiler használja a lebegőpontos egységet.
  • A memóriahozzáférés sokkal drágább, mint az asztali gépekben. A memcpy is!

Assembly

  • XCode-ban lehet inline Assembly-t írni.
  • A C-változatot is meg kell hagyni, mert a Simulatorhoz felesleges külön Assembly verzió. A Simulator x86-os, a régebbi iOS eszközök-ok ARM6-os (VFP), iPhone 3GS-től felfelé pedig ARM7-es (Neon) kódot kérnek.
  • Universal binary kell (Build Settings - Architectures - Standard (armv7 armv7), illetve -mfloat-abi=softfp -mfpu=neon kapcsolók (Other C Flags).
  • Az Assembly-be átírás nem triviális, ne "automatikusan" csináljuk. Jó Assembly kód csak "kézműves" munka eredménye lehet.
  • A regiszterek hatékony kihasználása, a lehető legkevesebb memóriahozzáférés (és lehetőleg blokkban), valamint az utasítások ciklusszámának ismerete sokszoros sebességkülönbséget jelent!
  • Minden utasítást adott számú ciklus alatt hajt végre a processzor, de képes többet párhuzamosan is!
  • Használjuk az "egybeépített" segédprocesszort, lebegőpontos számításokra (32 bit float), főleg vektorokhoz, mátrixokhoz. Egy ilyen szorzás pl. 8 ciklus alatt megy végbe, ez idő alatt mást is csinálhat a CPU, ha a következő utasítás nem a szorzás által használt regisztereken dolgozik (párhuzamosítás).

Példa: DJ PLAYER keverő (mixer) kód iPhone 2G-n

  • C: 18% CPU.
  • VFP Assembly, a ciklusszámok figyelembe vétele nélkül: 8% CPU.
  • Végleges, optimalizált változat: 2% CPU.

Kódok

Szálkezelés. Idle CPU mérés.

2 hozzászólás

  1. idézem 2011.05.11. 09:29
    tartalmas volt az eloadas, meg kosz az infokat utana.

    elfelejtettem megkerdezni, hogy hogyan valositottad meg: "Összegyűjteni a módosításokat (pl. UIButton.highlighted)"
    Sajat kod, vagy van ra sdk tamogatas?

    Udv,
    Feco
  2. idézem 2011.05.11. 09:34
    Nincs rá SDK támogatás, saját kóddal kell összegyűjteni, aztán CADisplayLink-kel időzítve végrehajtani. Sokféle stratégiát ki lehet alakítani rá.
Új hozzászólás
A sortörések automatikusak. Csak az üzenet kitöltése kötelező, a többi mező opcionális. A megadott e-mail címet nem tesszük közzé. Engedélyezett HTML tagek: p, a, strong, em, blockquote, ul, ol, li, dl, dt, dd.

Legutolsó hozzászólások

Rólam és a blogról: Papp Dávid: Szia, App fejlesztés ugyében szeretném veled felvenni a kapcsolatot. davidpapp89@gmail.com Üdv, Dávid

Diszkórobbanás a 90-es években és a legendás Campari diszkó: Mounaji Fatima: sziasztok!valóban jó volt a campari ,nekem a mai napig hiányzik.kacsa ,barbi,pg!ez bár a mult de még is jó visszagondolni rá!!bár ma is...

Diszkórobbanás a 90-es években és a legendás Campari diszkó: Árpika Palotáról: Szia ZooLou :-9 Te melyik részen melóztál?

Teh early agez... (így kezdődött) 1990-1992: Tamás Hölzer: Szia Gábor! Hozzájárulsz, hogy a http://zenci-blog.blogspot.com/p/disco-story.html blogban linkeljem a diszkó "történelmed"? Üdv; tamás

Diszkórobbanás a 90-es években és a legendás Campari diszkó: ZooLou: Finucsi, PG, Függöny, Dj Tökimanó, Barbi, Kacsa, Virág, Feri, Erzsi, Jana, és még sokan a csapatból! Én is lehúztam egy kis időt ott,...

iMect means internet, media and other cool things. We're a small company located in Hungary. There is a big footer on every page where you can discover what we do and what happens with us.

Az iMect jelentése: internet, média és egyéb király dolgok. Egy kis magyar cég vagyunk. Minden oldalon van egy nagy lábléc, ahol felfedezheted, hogy mivel foglalkozunk.