venerdì 25 ottobre 2013

Un viaggio attraverso il kernel - Parte 2b





Come avevo annunciato nello scorso articolo, ho diviso la seconda parte del viaggio attraverso il kernel in due sub capitoli, per poi lasciare spazio alla terza parte dedicata ai tweaks del kernel più completo in assoluto: il Dorimanx. 

In questa seconda metà del secondo episodio dell'editoriale, vedremo di dare risposta ad alcune domande per andare incontro ad interrogativi frequenti di chi, ad esempio, incontra microlag, fatica ad arrivare a fine giornata con la batteria etc. Inoltre vedremo alcuni tweaks da poter implementare, via script, al nostro kernel, più precisamente ai governor, per renderlo più performante e adattabile alle nostre esigenze.


La prima domanda al quale rispondiamo, anche abbastanza velocemente, è come cambio un governor?
Se hai avuto l'ardire di leggere questi articoli, o comunque di seguire questo blog, dovresti già saperlo, ma è comprensibile che ci sono tanti neofiti in questo campo, per cui è giusto rispondere minuziosamente. 
Solitamente, se si montano custom ROM esiste una sezione delle impostazioni dedicata a questo scopo (la si può trovare sotto Advanced options o su CPU control o simili). Se non si dispone di questa sezione si può far ricorso ad app di terze parti, quali No-Frills CPU ControlVoltage ControlCPU Adjuster e molte altre.

La domanda che, probabilmente, tutti si pongono è: qual è il miglior governor? Bella domanda che non ha risposta. Non esiste un miglior governor perché per esistere deve soddisfare tutte le richieste di ogni utente android sulla faccia della terra. Un po' complicata come cosa eh? 

Esistono diversi ottimi governor, ognuno adatto alle proprie esigente, ma prima di vedere quali, partiamo dal presupposto che Android (puro s'intende) è stato sviluppato con una certa logica alle spalle, ossia quella di girare ottimamente su una CPU con due core
Per cui, mi rivolgo ai possessori di quadcore o octacore (nominali, non è ancora sul mercato l'octacore puro, ci sta lavorando la Mediatek): i due core che avete in eccesso, sono superflui per l'uso quotidiano, disattivateli e farete un piacere alla vostra batteria.

Tornando al discorso, ci sono diversi governor perfetti per determinati utenti vediamoli:
se l'uso che si fa del device è un uso blando, tipo browser, applicazioni standard, social e simili, pegasusq o lulzactive sono perfetti per lo scopo. Risparmiano energia (nel caso del pegasusq, usando i core in asincronia) senza però andare ad intaccare le prestazioni.
Se si punta ad un uso determinato (per far girare giochi pesanti ad esempio) la scelta può ricadere su ondemand (che, ricordiamo, spara la CPU al massimo della sua frequenza ad ogni richiesta di processo) o su performance (che imposta la frequenza minima a quella massima). Ovvio che sono soluzioni più dispendiose in termini di batteria.

Spesso e volentieri, nonostante si usi un buon governor quale il lulzactive, è possibile incontrare dei microlag, ossia dei rallentamenti appena percettibili. Accade scrollando il browser o l'app drawer. È facile rimuovere questi microlag poiché essi sono dettati dal troppo efficiente governor che mira al risparmio energetico e abbassa velocemente (troppo) la frequenza della CPU. È possibile aumentare il valore di down_samplig_time in relazione all'up_sampling_time.
up_sampling_time è settato a 24000 per default sul lulzactive, il down_sampling_time deve avere un valore doppio o triplo e potete settarlo tramite uno script (che vedremo dopo come impostare): 
echo "70000" > /sys/device/system/cpu/cpufreq/lulzactive/down_sampling_rate

Qualche utente del forum che frequento (Androidiani.com) mi ha chiesto perché come valore minimo di frequenza della CPU non viene impostato i 100mhz (o addirittura inferiore), visto che ovunque il minimo è 200mhz. La risposta è tanto semplice quanto strana: a quanto pare, dei developer di XDA hanno riscontrato che lo step dei 100mhz consuma di più rispetto a quello dei 200mhz (1W/ghz dei 100mhz contro lo 0,7W/ghz dei 200mhz) ed inoltre con i 200mhz si ha un responso più efficace dalla CPU. Inoltre i 200mhz sono il punto energicamente più efficiente di tutti gli step di frequenza, ossia quello dove a parità di energia ed in relazione alla frequenza, vengono eseguite più operazioni più velocemente.

Ci sono alcune persone che preferiscono una maggiore reattività del telefono, anche a scapito della batteria. È possibile ottenere questo risultato, semplicemente settando come frequenza minima d'esercizio un valore più alto rispetto agli standard 200mhz (valori come 500mhz sono ottimali).

Viceversa ci sono altre persone che vorrebbero una durata maggiore della batteria: a tal proposito è sufficiente limitare la frequenza massima d'esercizio della CPU a valori come 800mhz o 1000mhz, comunque ottimali se si è in possesso di un dual core (o maggiori) e non si fa uso di giochi troppo pesanti. Il telefono comunque è pur sempre reattivo e stabile.

Per quanto riguarda gli scheduler (che, come potete ricordarvi dal precedente paragrafo, sono coloro che si occupano di riordinare i processi da far eseguire alla CPU) il discorsi è simile a quello dei governor. Non esiste uno scheduler perfetto e definitivo: esistono una varietà di scheduler ottimi per diverse funzioni. Il SIO o il BFQ sono due buoni compromessi tra velocità USB e riduzione di latenza dei processi.
Per le prestazioni, invece, Deadline è perfetto per eseguire tutti i processi al massimo della velocità possibile.



Veniamo al nocciolo della questione. Vediamo dunque come tweakare tramite script init.d i nostri governor.
Cos'è uno script e cosa si intende con init.d.
Uno script è un particolare programma che non dispone di un'interfaccia grafica, relativamente semplice da scrivere e da interpretare, che fa utilizzo di diversi linguaggi di programmazione. 
Viene avviato durante il caricamento dell'userspace, ossia la terza parte di avvio di android, dopo l'avvio del bootloader e dopo il caricamento del kernel.
init.d, o meglio /etc/init.d (/system/etc/init.d) è una cartella contenente diversi script che vengono eseguiti ad ogni avvio del device. Non tutte le ROM dispongono del supporto a questa cartella, informatevi che funzioni sulla vostra ROM prima di iniziare questa procedura. Se non siete in grado di eseguire script init.d sul vostro device, chiedete il supporto al dev oppure fate uso a vostro rischio e pericolo di questa app.

Lo script è un file di testo senza estensione alcuna, con all'interno del codice, preceduto da una riga di invocazione di una shell o di un interprete, solitamente sono due busybox o sh:

#!/sbin/busybox sh o #!system/xbin/busybox sh (a seconda della locazione di busybox nel vostro sistema)

oppure

#!/system/bin/sh

Noi andremo a vedere gli script che fanno uso della shell #!/system/bin/sh.
Un mio personale consiglio è quello di non usare l'editor di testo di default di Windows perché spesso lascia spazi indesiderati che mandano in errore lo script. Preferite piuttosto Notepad++ se siete su Windows/Linux, TextWrangler se siete su Mac o Gedit se siete su Linux. 

Come si crea uno script?
È relativamente semplice, ciò che vi serve è il testo dello script, un root browser, un editor di testo e l'applicazione Script Manager.

  • Scrivete lo script su un file di testo vuoto e posizionatelo nella memoria del telefono.
  • Eliminate l'estensione .txt (non deve avere estensione alcuna).
  • Montate la root di sistema (/) come R/W.
  • Tramite un Root browser posizionate il file nella cartella /etc/init.d.
  • Abilitate i permessi allo script dandoglieli tutti e 9.
  • Con Script Manager abilitatelo andando nel percorso dello script ed abilitando su boot.
  • Smontate la root di sistema da R/W
Una volta compresa questa procedura, andiamo a vedere come tweakare i nostri governor.

Con tweak si intende una modifica atta a migliorare le prestazioni di un determinato parametro e noi, come detto, lo andremo a fare tramite script init.d. 
I governor che andremo a tweakare sono: Ondemand, Lulzactive, SmartassV2 e Conservative


Vediamo come migliorare le performance del governor Ondemand. Lo possiamo fare settando valori bassi di up_threshold e sampling_rate, in modo che il governor interroghi meno spesso la CPU, lasciandola a valori alti e lasciandola scalare più lentamente verso valori bassi.
Nel file di testo scriviamo l'invocatore #!/system/bin/sh all'inizio e successivamente, in altre righe, lo script (il testo degli script è visualizzato con tag html <code> per cui lo vedrete con font differente):

#!/system/bin/sh
echo "70" > /sys/devices/system/cpu/cpufreq/ondemand/up_threshold
echo "50000" > /sys/devices/system/cpu/cpufreq/ondemand/sampling_rate
echo "2" > /sys/devices/system/cpu/cpufreq/ondemand/sampling_down_factor
echo "15" > /sys/devices/system/cpu/cpufreq/ondemand/down_differential
echo "50" > /sys/devices/system/cpu/cpufreq/ondemand/freq_step


Come potete vedere, abbiamo settato a 70 il valore di up_threshold, 50000 quello di sampling_rate, 2 sampling_down_factor, 15 down_differential e 50 freq_step.

Vediamo uno script opposto, atto migliorare la batteria a scapito delle prestazioni.

#!/system/bin/sh
echo "95" > /sys/devices/system/cpu/cpufreq/ondemand/up_threshold
echo "120000" > /sys/devices/system/cpu/cpufreq/ondemand/sampling_rate
echo "1" > /sys/devices/system/cpu/cpufreq/ondemand/sampling_down_factor
echo "5" > /sys/devices/system/cpu/cpufreq/ondemand/down_differential
echo "10" > /sys/devices/system/cpu/cpufreq/ondemand/freq_step


Notate i valori nettamente differenti rispetto allo script precedente.

È giunta l'ora di modificare i parametri del Lulzactive e lo faremo modificando il tempo di campionamento della CPU per scalare le frequenze (up/down_sample_time).

Per migliorare la batteria facciamo sì che il governor interroghi più spesso la CPU:

#!/system/bin/sh
echo "90" > /sys/devices/system/cpu/cpufreq/lulzactive/inc_cpu_load
echo "1" > /sys/devices/system/cpu/cpufreq/lulzactive/pump_up_step
echo "2" > /sys/devices/system/cpu/cpufreq/lulzactive/pump_down_step
echo "50000" > /sys/devices/system/cpu/cpufreq/lulzactive/up_sample_time
echo "40000" > /sys/devices/system/cpu/cpufreq/lulzactive/down_sample_time
echo "5" > /sys/devices/system/cpu/cpufreq/lulzactive/screen_off_min_step


Per migliorare le prestazioni compiamo l'azione opposta, meno interrogazioni e più lavoro:

#!/system/bin/sh
echo "60" > /sys/devices/system/cpu/cpufreq/lulzactive/inc_cpu_load
echo "4" > /sys/devices/system/cpu/cpufreq/lulzactive/pump_up_step
echo "1" > /sys/devices/system/cpu/cpufreq/lulzactive/pump_down_step
echo "10000" > /sys/devices/system/cpu/cpufreq/lulzactive/up_sample_time
echo "70000" > /sys/devices/system/cpu/cpufreq/lulzactive/down_sample_time
echo "5" > /sys/devices/system/cpu/cpufreq/lulzactive/screen_off_min_step


Per bilanciare prestazioni e batteria facciamo sì che il governor interroghi la CPU spesso, ma che la porti verso l'alto solo col 90% di carico:

#!/system/bin/sh
echo "90" > /sys/devices/system/cpu/cpufreq/lulzactive/inc_cpu_load
echo "4" > /sys/devices/system/cpu/cpufreq/lulzactive/pump_up_step
echo "1" > /sys/devices/system/cpu/cpufreq/lulzactive/pump_down_step
echo "10000" > /sys/devices/system/cpu/cpufreq/lulzactive/up_sample_time
echo "40000" > /sys/devices/system/cpu/cpufreq/lulzactive/down_sample_time
echo "5" > /sys/devices/system/cpu/cpufreq/lulzactive/screen_off_min_step


Passiamo adesso allo SmartAssV2, governor già bilanciato di suo.

Per migliorare la durata della batteria:

#!/system/bin/sh
echo "500000" > /sys/devices/system/cpu/cpufreq/smartass/awake_ideal_freq;
echo "200000" > /sys/devices/system/cpu/cpufreq/smartass/sleep_ideal_freq;
echo "500000" > /sys/devices/system/cpu/cpufreq/smartass/sleep_wakeup_freq
echo "85" > /sys/devices/system/cpu/cpufreq/smartass/max_cpu_load;
echo "70" > /sys/devices/system/cpu/cpufreq/smartass/min_cpu_load;
echo "200000" > /sys/devices/system/cpu/cpufreq/smartass/ramp_up_step;
echo "200000" > /sys/devices/system/cpu/cpufreq/smartass/ramp_down_step;
echo "48000" > /sys/devices/system/cpu/cpufreq/smartass/up_rate_us
echo "49000" > /sys/devices/system/cpu/cpufreq/smartass/down_rate_us


Per migliorare le performance:

#!/system/bin/sh
echo "800000" > /sys/devices/system/cpu/cpufreq/smartass/awake_ideal_freq;
echo "200000" > /sys/devices/system/cpu/cpufreq/smartass/sleep_ideal_freq;
echo "800000" > /sys/devices/system/cpu/cpufreq/smartass/sleep_wakeup_freq
echo "75" > /sys/devices/system/cpu/cpufreq/smartass/max_cpu_load;
echo "45" > /sys/devices/system/cpu/cpufreq/smartass/min_cpu_load;
echo "0" > /sys/devices/system/cpu/cpufreq/smartass/ramp_up_step;
echo "0" > /sys/devices/system/cpu/cpufreq/smartass/ramp_down_step;
echo "24000" > /sys/devices/system/cpu/cpufreq/smartass/up_rate_us
echo "99000" > /sys/devices/system/cpu/cpufreq/smartass/down_rate_us


Passiamo adesso a tweakare il governor Conservative, che riesce ad ottenere straordinarie prestazioni, con un occhio di riguardo alla batteria (abbastanza ironico).

Per migliorarlo in termini di batteria è possibile settare valori di freq_step ancora più bassi:

#!/system/bin/sh
echo "95" > /sys/devices/system/cpu/cpufreq/conservative/up_threshold
echo "120000" > /sys/devices/system/cpu/cpufreq/conservative/sampling_rate
echo "1" > /sys/devices/system/cpu/cpufreq/conservative/sampling_down_factor
echo "40" > /sys/devices/system/cpu/cpufreq/conservative/down_threshold
echo "10" > /sys/devices/system/cpu/cpufreq/conservative/freq_step


Per migliorarlo in performance:

#!/system/bin/sh
echo "60" > /sys/devices/system/cpu/cpufreq/conservative/up_threshold
echo "40000" > /sys/devices/system/cpu/cpufreq/conservative/sampling_rate
echo "5" > /sys/devices/system/cpu/cpufreq/conservative/sampling_down_factor
echo "20" > /sys/devices/system/cpu/cpufreq/conservative/down_threshold
echo "25" > /sys/devices/system/cpu/cpufreq/conservative/freq_step


E per ultimo vediamo come tweakare il governor Interactive.

Per migliorarlo in termini di risparmio energetico abbassiamo il valore di hispeed_freq:

#!/system/bin/sh
echo "95" > /sys/devices/system/cpu/cpufreq/interactive/go_hispeed_load
echo "1000000" > /sys/devices/system/cpu/cpufreq/interactive/hispeed_freq
echo "10000" > /sys/devices/system/cpu/cpufreq/interactive/min_sample_time
echo "40000" > /sys/devices/system/cpu/cpufreq/interactive/timer_rate


Per migliorarlo in termini di performance dobbiamo procedere solo se lo step di frequenza massimo è almeno 1,4ghz.

#!/system/bin/sh
echo "80" > /sys/devices/system/cpu/cpufreq/interactive/go_hispeed_load
echo "1400000" > /sys/devices/system/cpu/cpufreq/interactive/hispeed_freq
echo "40000" > /sys/devices/system/cpu/cpufreq/interactive/min_sample_time
echo "20000" > /sys/devices/system/cpu/cpufreq/interactive/timer_rate


Con quest'ultimo script abbiamo completato una basilare guida su come andare ad interagire con i governor, modulandoli a nostro piacimento. I valori riportati sono frutto dell'esperienza di diversi guru di XDA e di alcuni top user di Androidiani.com per cui sono già ampiamente testati prima di venire pubblicati.

Come consiglio preliminare vi dico sempre di eseguire un nandroid backup prima di mettersi a tweakare il kernel e soprattutto di leggere tutto e di essere certi di comprenderlo. Un errore è sufficiente per surriscaldare il device e bruciare il chip della CPU e quindi danneggiare irreparabilmente la scheda madre. Per cui state attenti a quel che combinate.

Nella terza parte di questo viaggio nel kernel, l'ultima, parleremo del kernel Dorimanx e dell'applicazione Stweaks, citando ed approfondendo tutti i valori modificabili (via script o via app) in modo da capirli e poter agire su di essi.

Alla prossima!