So korrigieren Sie das Timing von Android-RenderScript-Code auf Nvidia Shield

Ich habe einen kleinen CNN in RenderScript implementiert und möchte die Leistung auf unterschiedlicher Hardware darstellen. Auf meinem Nexus 7 machen die Zeiten Sinn, auf dem NVIDIA Shield aber nicht.

Das CNN (LeNet) ist in 9 Schichten implementiert, die sich in einer Warteschlange befinden. Die Berechnung erfolgt nacheinander. Jede Ebene wird einzeln zeitgesteuert.

Hier ist ein Beispiel

       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

Die Verteilung der Zeiten ist für den Nexus ungefähr richtig, wobei conv1 und conv2 (Convolution Layer) die meiste Zeit in Anspruch nehmen. Aber auf dem Schild fallen die Zeiten weit über das für die Schichten 2 bis 4 Vernünftige hinaus und scheinen sich gegen Ende zu sammeln. Die Softmax-Schicht ist eine relativ kleine Aufgabe, daher sind 40 ms viel zu groß. Meine Timing-Methode muss fehlerhaft sein oder es ist etwas anderes los.

Der Code, der die Ebenen ausführt, sieht ungefähr so aus:

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++;
}

ach meinem Verständnis soll der Job beendet sein, sobald forEach_ () zurückkehrt. In jedem Fall sollte mRS.finish () eine letzte Barriere darstellen. Aus heutiger Sicht ist die einzige vernünftige Erklärung, dass Jobs immer noch im Hintergrund verarbeitet werden.

Die App ist sehr einfach, ich führe nur den Test von MainActivity aus und drucke auf logcat. Android Studio erstellt die App als Release und führt sie auf dem Gerät aus, das über USB angeschlossen ist.

(1) Was ist der richtige Weg, um RenderScript-Prozesse zeitlich zu steuern? (2) Stimmt es, dass bei der Rückkehr von forEach_ () die vom Skript erzeugten Threads garantiert ausgeführt werden? (3) In meiner Test-App starte ich einfach direkt von der MainActivity aus. Ist dies ein Problem (außer das Blockieren des UI-Threads und das Deaktivieren der App)? Wenn dies das Timing beeinflusst oder die Verrücktheit verursacht, wie kann man eine Test-App wie diese einrichten?

Antworten auf die Frage(4)

Ihre Antwort auf die Frage