Ho implementato una piccola CNN in RenderScript e desidero profilare le prestazioni su hardware diversi. Sul mio Nexus 7 i tempi hanno senso, ma su NVIDIA Shield non lo fanno.Come eseguire la sincronizzazione corretta del codice Android RenderScript su Nvidia Shield
La CNN (LeNet) è implementata in 9 livelli che risiedono in una coda, il calcolo viene eseguito in sequenza. Ogni livello è cronometrato individualmente.
Ecco un esempio:
conv1 pool1 conv2 pool2 resh1 ip1 relu1 ip2 softmax
nexus7 11.177 7.813 13.357 8.367 8.097 2.1 0.326 1.557 2.667
shield 13.219 1.024 1.567 1.081 0.988 14.588 13.323 14.318 40.347
La distribuzione dei tempi sono circa proprio per il nesso, con CONV1 e CONV2 (strati di convoluzione) occupa la maggior parte del tempo. Ma sullo scudo, i tempi scendono molto oltre ciò che è ragionevole per i livelli 2-4 e sembrano radunarsi verso la fine. Lo strato di softmax è un lavoro relativamente piccolo, quindi 40 ms è troppo grande. Il mio metodo di cronometraggio deve essere difettoso, o qualcos'altro sta succedendo.
Il codice in esecuzione gli strati simile a questa:
double[] times = new double[layers.size()];
int layerindex = 0;
for (Layer a : layers) {
double t = SystemClock.elapsedRealtime();
//long t = System.currentTimeMillis(); // makes no difference
blob = a.forward(blob); // here we call renderscript forEach_(), invoke_() etc
//mRS.finish(); // makes no difference
t = SystemClock.elapsedRealtime() - t;
//t = System.currentTimeMillis() - t; // makes no difference
times[layerindex] += t; // later we take average etc
layerindex++;
}
E 'la mia comprensione che una volta forEach_() ritorna, si suppone il lavoro da finire. In ogni caso, mRS.finish() dovrebbe fornire una barriera finale. Ma guardando i tempi, l'unica spiegazione ragionevole è che i lavori vengano ancora elaborati in background.
L'app è molto semplice, ho appena eseguito il test da MainActivity e stampato su logcat. Android Studio crea l'app come una versione e la esegue sul dispositivo che è collegato tramite USB.
(1) Qual è il modo corretto di eseguire i processi di RenderScript? (2) È vero che quando forEach_() restituisce, i thread generati dallo script sono garantiti per essere eseguiti? (3) Nella mia app di test, eseguo semplicemente direttamente da MainActivity. Si tratta di un problema (oltre a bloccare il thread dell'interfaccia utente e rendere l'app non risponde)? Se questo influenza il tempismo o causa la stranezza, qual è il modo corretto per impostare un'app di prova come questa?
CNN sta per? –
Rete neurale involutiva. – frankhond