di  -  lunedì 6 giugno 2011

Nello scorso articolo abbiamo evidenziato, tramite osservazione diretta, alcune problematiche macroscopiche che rendono difficile, nello specifico, creare delle animazioni grafiche perfettamente fluide sullo smartphone Nokia 5800 XpressMusic. Riepilogo velocemente i passaggi precedenti:

  • Ho creato dei testbench programmati ad hoc su Nintendo DS e su Nokia 5800 XpressMusic (Symbian 9.4)
  • Dalle misurazioni effettuate risulta che, in software rendering, il Nintendo DS impiega circa 15ms per disegnare una schermata intera, mentre lo smartphone impiega solo 5ms. Non sono stati sfruttati i coprocessori grafici del DS per il test.
  • Dalla misurazione del framerate risulta però che il DS ottiene 60 frames al secondo, mentre lo smartphone si assesta su una media di 20 FPS.
  • Esiste quindi una latenza stimata rispettivamente in 1 millisecondo per il DS e 35 millisecondi sullo smartphone.

In questo articolo vedremo in che modo venga generata questa latenza e quali siano le possibili soluzioni per porvi rimedio.

Le prime considerazioni, come intuibile, sono relative al multitasking, cioè alla compresenza di più processi eseguiti in rapida successione dall’OS, in modo tale da dare l’impressione di essere eseguiti in parallelo.

Come funziona questo meccanismo? In breve, tutto il meccanismo si basa sul concetto di Interrupt (o interruzione).

Esiste, cioè, la possibilità di interrompere la CPU durante la sua normale esecuzione del codice, per fargli eseguire dei compiti più urgenti, e riprendere in seguito il lavoro interrotto.

Esistono tante fonti di interruzioni, ma quella che ci interessa in questo momento è data dal cosiddetto Clock Generator. Il suo funzionamento è analogo a quello del clock di sistema, che genera un segnale ad onda rettangolare usato per sincronizzare tutti i componenti del sistema.

La frequenza di questo Clock Generator può essere variata dal software, ed è in genere molto bassa rispetto al clock di sistema.

Nei dispositivi Symbian tale frequenza di interrupt si aggira intorno al millisecondo, quindi all’interno del tempo di un frame avvengono circa 15-16 interruzioni programmate.

A queste si sommano le interruzioni generate da altro hardware, tipicamente le periferiche legate alla gestione radio (GSM, UMTS, Wifi), le cui interruzioni devono essere servite con altissima priorità.

Inoltre, avviene un cambio di processo (Context Switch) alla frequenza di 64Hz (64 volte al secondo). Tale è infatti la durata del cosiddetto “tick” del kernel, cioè la durata minima assegnata all’esecuzione di ogni processo. Ciò significa che il sistema operativo interromperà il nostro processo ogni 1/64 di secondo, circa 15.6 millisecondi, mentre la durata di un frame grafico è di 16.7 millisecondi. Va da se che durante il disegno di una schermata, possiamo avere minimo 1 context switch, ma a volte sono addirittura 2 e se il processo in background ha priorità Real Time, il nostro programma dovrà aspettare ulteriormente (perdendo altri 2-3 tick) finchè questo non termina il suo task.

Questo è uno dei motivi che impediscono al nostro programma di aggiornare lo schermo esattamente 60 volte al secondo.

Il secondo, importante motivo, è dovuto al gestore del display. Sui dispositivi sprovvisti di GPU, Symbian sfrutta la normale RAM di sistema come framebuffer e si occupa di trasferire il contenuto del framebuffer al display controller tramite trasferimenti rapidi per mezzo di un canale DMA dedicato.

Il meccanismo è discretamente sofisticato, nel senso che viene inviata al display soltanto una piccola porzione rettangolare di schermo, quella contenente dati “freschi”, cioè quelle parti di schermo che sono state aggiornate. Grazie a ciò, possiamo raggiungere animazioni fluide soltanto con piccoli oggetti, in modo tale da trasferire piccole quantità di dati dalla RAM al display controller, ma quando gli aggiornamenti riguardano l’intero schermo dobbiamo sostanzialmente copiare 2 volte gli stessi dati: la prima volta dobbiamo renderizzare gli oggetti sul framebuffer tramite CPU, e la seconda volta questo framebuffer viene copiato sul controller tramite DMA.

I canali DMA hanno priorità sulla CPU quindi finchè il DMA non termina la CPU sarà ferma a girarsi i pollici. Inoltre ci sono altri canali DMA (quelli che vanno da/verso la RAM e le periferiche radio) che hanno priorità maggiore rispetto al DMA video.

Tirando le somme, ci sono 3 motivi importanti che impediscono ad un sistema di software rendering di raggiungere le prestazioni massime di 60 frames al secondo:

  • I context switch non sono sincroni con l’aggiornamento dello schermo. Ciò rende impossibile temporizzare il codice, come si fa normalmente sui dispositivi dotati di temporizzazioni sincrone con lo schermo. Questa parte si potrebbe risolvere modificando il tick da 1/64 di secondo ad un sottomultiplo della frequenza di aggiornamento dello schermo, ad esempio 1/120 di secondo. Sul Nintendo DS gli interrupt non sincroni esistono (per il Wifi) ma vengono gestiti dal processore secondario. La CPU principale viene interrotta dagli interrupt di Vertical e Horizontal Blank, che non disturbano ma anzi aiutano ad aggiornare la grafica in perfetta sincronia con l’aggiornamento del display.
  • I processi in Real Time hanno priorità assoluta su tutto il resto. Dal momento che in Symbian questi sono i processi legati alla gestione radio, basta disattivare le comunicazioni radio (Bluetooth, Wifi, GSM/UMTS). Ciò impedisce tuttavia la possibilità di avere giochi multiplayer che al tempo stesso siano fluidi al massimo.
  • Il display controller non ha VRAM mappata in memoria, quindi richiede un trasferimento DMA alla fine del rendering di un frame. Un display dotato di VRAM mappabile in memoria (come appunto nel Nintendo DS) consentirebbe di sostituire la chiamata al DMA con un semplice bank switch, accorciando molto i tempi. Tale problema trova attualmente soluzione nei dispositivi dotati di GPU, a patto di sostituire la grafica 2D pura con grafica poligonale, in modo da evitare (o limitare al minimo) trasferimenti da RAM a GPU.

Con questo articolo spero di aver stuzzicato la vostra curiosità nei confronti dei sistemi operativi Real Time, e del funzionamento generale di un Sistema Operativo multitasking. Nei prossimi articoli entreremo dentro un tipico Sistema Operativo, e ne studieremo da vicino i meccanismi che ne consentono il multitasking.

4 Commenti »

I commenti inseriti dai lettori di AppuntiDigitali non sono oggetto di moderazione preventiva, ma solo di eventuale filtro antispam. Qualora si ravvisi un contenuto non consono (offensivo o diffamatorio) si prega di contattare l'amministrazione di Appunti Digitali all'indirizzo info@appuntidigitali.it, specificando quale sia il commento in oggetto.

  • # 1
    Massimo M
     scrive: 

    Programmo su sistemi embedded realtime, e mi interessa molto questo articolo.
    Prima domanda (ho paura che ne seguiranno molte … !): se abbasso la priorità della gestione radio per avere fluidità presumo che le comnicaz non vadano più. E’ questo che viene inteso con “impedisce tuttavia la possibilità di avere giochi multiplayer che al tempo stesso siano fluidi al massimo” ?
    Ok per la gestione del DMA (che purtroppo conosco bene …), ma solitamente il trasferimento di un blocco di memoria da un ind ad un altro vine comunque gestito in maniera più efficente e veloce. Non è possibile (con hw dedicato) interrompere questo flusso per far compiere alla cpu operazioni “urgenti”. Oppure, sempre su dma, se si esclude la comunicaz radio (nelle sue varie forme) allora il dma, che ha priorità anch’esso, non è necessario sia interrompibile e quindi può agire a piena potenza.
    Certo è che parlando di smartPHONE si intende che la prima cosa che debbono fre (ed anche bene) è la gestione radio (cioè teleofnare!). L’opportunità di disabilitare questa funzione per “giocare meglio” mi sembra più una disquisizione didattica che una realtà plausibile.
    Cmq buon articolo, il prob adesso è aspettare il prossimo episodio.
    Consiglio in futuro un breve resoconto si sist op realtime …

  • # 2
    Antonio Barba (Autore del post)
     scrive: 

    ciao Massimo, cercherò di rispondere alle domande con quello che sono riuscito a comprendere dai miei studi :-)

    Prima domanda (ho paura che ne seguiranno molte … !): se abbasso la priorità della gestione radio per avere fluidità presumo che le comnicaz non vadano più. E’ questo che viene inteso con “impedisce tuttavia la possibilità di avere giochi multiplayer che al tempo stesso siano fluidi al massimo” ?

    Esatto. Considera inoltre che non puoi modificare, su uno smartphone standard, la priorità dei processi Real Time, a meno che tu non stia utilizzando Symbian su una devboard (ad esempio la Beagle Board) e sia quindi in grado di agire a livello di OS.
    In generale per fare ciò su di uno smartphone è necessario acquistare un devkit molto costoso che ti consente di avere il pieno controllo della macchina, roba usata soltanto dai produttori di device per scrivere i propri drivers (Nokia stessa ad esempio).

    Ok per la gestione del DMA (che purtroppo conosco bene …), ma solitamente il trasferimento di un blocco di memoria da un ind ad un altro vine comunque gestito in maniera più efficente e veloce. Non è possibile (con hw dedicato) interrompere questo flusso per far compiere alla cpu operazioni “urgenti”. Oppure, sempre su dma, se si esclude la comunicaz radio (nelle sue varie forme) allora il dma, che ha priorità anch’esso, non è necessario sia interrompibile e quindi può agire a piena potenza.

    Da quello che si evince dalla documentazione (un po’ scarsa in verità), vi sono diversi canali DMA a priorità fissa. La priorità più alta è affidata al DMA che gestisce le comunicazioni radio, dopo viene il DMA del video, poi quello dello storage (SD, Flash interna, ecc…).
    Disattivando le comunicazioni radio (modalità aereoplano) si può misurare un discreto aumento di prestazioni, proprio perchè quasi tutti i processi Real Time vengono sospesi e di conseguenza nessuno programmerà un trasferimento DMA da/verso l’hardware radio.
    Con il test da me effettuato, un semplice blitting a pieno schermo, si riusciva a sfiorare il pieno framerate (tuttavia non in modo costante).
    Aumentando la complessità della scena la mancanza di sincronia tra il tick del kernel e il refresh video si fa sentire, perchè in tal caso il tick può cadere anche durante il DMA transfer di una riga (non viene trasferita l’intera schermata, solo una regione per volta) creando un fastidioso effetto “tearing”, cioè vedi mezzo schermo del vecchio frame e mezzo schermo nuovo.
    Nei dispositivi provvisti di GPU tale problema non sussiste, perchè vengono precaricati i dati sulla memoria video ed il rendering avviene in modo asincrono rispetto alla CPU.

  • # 3
    Antonio Barba (Autore del post)
     scrive: 

    … il problema non sussiste nemmeno su una console come il Nintendo DS, perchè in quel caso posso tranquillamente prendermela comoda durante il rendering, facendo un bank switch alla fine di esso, in sincrono con il VBlank. In quel caso, mentre preparo la nuova schermata su uno dei banchi di VRAM, ad esempio sul bank A, il display viene aggiornato usando il contenuto del bank B. In questo modo è impossibile provocare “tearing”. Inoltre le comunicazioni radio sono gestite da una seconda CPU, quindi il tutto è perfettamente robusto e fornisce tempi di risposta perfettamente deterministici.

  • # 4
    [D]
     scrive: 

    Insomma la morale è che il sistema, giustamente, ha delle preferenze verso il networking a scapito di tutto il resto (in fin dei conti, comprare uno smartphone per giocare non merita commenti, fatti un DS e vivi felice) e se l’hardware manca di alcune cosette in quanto progettato al risparmio sono… context switches nel senso di volatili per diabetici, di treni e gallerie…

Scrivi un commento!

Aggiungi il commento, oppure trackback dal tuo sito.

I commenti inseriti dai lettori di AppuntiDigitali non sono oggetto di moderazione preventiva, ma solo di eventuale filtro antispam. Qualora si ravvisi un contenuto non consono (offensivo o diffamatorio) si prega di contattare l'amministrazione di Appunti Digitali all'indirizzo info@appuntidigitali.it, specificando quale sia il commento in oggetto.