Ich habe kürzlich angefangen, über Benchmarks zu lesen und sie für Android (in Java) zu schreiben. Mir sind solche Probleme wie Warmups, Garbage Collector und Compiler-Optimierungen bekannt, aber ich weiß nicht, ob das Problem, auf das ich stoße, von einem dieser Probleme verursacht werden könnte.Warum verursacht das Hinzufügen lokaler Variablen eine Verzögerung der Methode?
In meiner Benchmark-App erstelle ich ein Array von 10.000 Float-Variablen und initialisiere es mit zufälligen Werten. Wenn Benchmark-Code ausgeführt wird:
private void runMinorBenchmarkFloat (float[] array) {
float sum = 0;
long startTime;
long endTime;
/* Fast warm-up */
startTime = System.nanoTime();
for(int i=0; i<SMALL_LOOP_ITERATION_COUNT; i++)
for(int j=0; j<TAB_SIZE; j++)
sum += array[j];
endTime = System.nanoTime() - startTime;
postMessage("Warm-up for FLOAT finished in: " + endTime/1000000 + "ms.\n");
/* Main benchmark loop */
startTime = System.nanoTime();
for(int i=0; i<BIG_LOOP_ITERATION_COUNT; i++)
{
sum = 0;
for(int j=0; j<TAB_SIZE; j++)
sum += array[j];
}
endTime = System.nanoTime() - startTime;
postMessage("Benchmark for FLOAT finished in: " + endTime/1000000 + "ms.\n");
postMessage("Final value: " + sum + "\n\n");
}
auf meinem Handy bekomme ich ca. 2 Sekunden für Warm-up und 20 Sekunden für die „echte“ Schleife.
Nun, wenn ich hinzufügen, zwei weitere Variablen vom Typ float (sum2 und SUM3 - nie in der Methode verwendet wird):
private void runMinorBenchmarkFloat (float[] array) {
float sum = 0, sum2 = 0, sum3 = 0; // <------- the only code change here!!!
long startTime;
long endTime;
/* Fast warm-up */
startTime = System.nanoTime();
for(int i=0; i<SMALL_LOOP_ITERATION_COUNT; i++)
for(int j=0; j<TAB_SIZE; j++)
sum += array[j];
endTime = System.nanoTime() - startTime;
postMessage("Warm-up for FLOAT finished in: " + endTime/1000000 + "ms.\n");
/* Main benchmark loop */
startTime = System.nanoTime();
for(int i=0; i<BIG_LOOP_ITERATION_COUNT; i++)
{
sum = 0;
for(int j=0; j<TAB_SIZE; j++)
sum += array[j];
}
endTime = System.nanoTime() - startTime;
postMessage("Benchmark for FLOAT finished in: " + endTime/1000000 + "ms.\n");
postMessage("Final value: " + sum + "\n\n");
}
Ausführungszeit von 2 Sekunden springt für Warm-up auf 5 Sekunden und 20 Sekunden für echte Schleife bis 50 Sekunden.
Die Konstanten:
SMALL_LOOP_ITERATION_COUNT = 100,000
BIG_LOOP_ITERATION_COUNT = 1,000,000
Glauben Sie, dass diese Differenz durch Ausrichtungsprobleme verursacht werden könnten (nur lose Idee)?
Vielen Dank im Voraus für alle Antworten.
EDIT:
Es scheint, wie diese Fehler auf jedem Gerät nicht angezeigt. Ich kann es auf dem Samsung Galaxy S5 reproduzieren. Das Hauptziel des Programms war, wenig Benchmark zu machen. Ich habe vier fast-die gleichen Funktionen (runMinorBenchmark____ wo _ war entweder: int, kurz, float, double), die nur in der Variable 'sum' Typ unterschieden. In der Hauptbewertungsfunktion habe ich diese Funktionen aufgerufen. Da der erwähnte Fehler aufgetreten ist, habe ich mich entschlossen, diese Funktion in eine große zusammenzufassen. Jetzt ... Beim Testlauf habe ich solche Zeiten: 1. 37640ms. (für int) 2. 46728ms. (kurz) 3. 60589ms. (für Schwimmer) 4. 34467ms. (für Doppel)
Ich weiß, dass kurze soll wegen Typ Gießen langsamer sein. Ich dachte auch, dass Float langsamer sein sollte, wenn man es zu verdoppeln versucht (vielleicht gibt FPU den Casting-Befehl jedes Mal doppelt (?)). Aber wenn ich den Variablentyp für sumFloat von float auf double ändere, ist die Zeit für float identisch mit double time. Ich habe auch diese "Benchmark" auf einem anderen Gerät, das nicht von diesem seltsamen Verhalten zu leiden schien und die Zeiten für jeden Test waren fast gleich: ~ 45000ms. (wirklich keine sichtbaren Unterschiede).
Dalvik VM Fehler (?)
Nein. Das Hinzufügen von zwei "unbenutzten" Feldern hat keinen Einfluss auf die tatsächliche Laufzeit der Schleife. Etwas anderes muss falsch sein. – TheLostMind
Ich stimme @TheLostMind zu. Das Hinzufügen von zwei Float-Variablen sollte die Ausführungszeit nicht wesentlich verlängern. Wie Sie sehen können, kann die CPU 10.000 Floats sehr schnell verarbeiten, also gibt es keinen Grund, warum es nicht in der Lage sein sollte, diese beiden schnell zu verarbeiten. – erad
Danke für die Antworten. Ich stimme euch beiden zu, aber das ist es, was wirklich passiert. Haben Sie Ideen, wo Sie weiter suchen können? – Waszker