Ist die Multiplikation schneller als der Array-Zugriff?

8

Zu meiner Überraschung bekomme ich eine längere Zeit (10 Millisekunden), wenn ich Multiplikationen "optimiere", indem ich die Ergebnisse in einem Array im Vergleich zu den ursprünglichen 8 Millisekunden vorgeneriere. Ist das nur eine Java-Eigenart oder ist das die allgemeine PC-Architektur? Ich habe einen Core i5 760 mit Java 7, Windows 8 64 Bit.

%Vor%     
Konrad Höffner 03.02.2014, 23:29
quelle

2 Antworten

12

Konrad Rudolph kommentierte die Probleme mit dem Benchmarking . Also ignoriere ich den Benchmark und konzentriere mich auf die Frage:

  

Ist die Multiplikation schneller als der Array-Zugriff?

Ja, das ist sehr wahrscheinlich. Früher war es vor 20 oder 30 Jahren andersherum.

Grob gesagt, können Sie eine Integer-Multiplikation in 3 Zyklen durchführen (pessimistisch, wenn Sie keine Vektorinstruktionen erhalten), und ein Speicherzugriff kostet Sie 4 Zyklen, wenn Sie direkt aus der L1 Cache, aber von dort ist es direkt bergab. Als Referenz siehe

Eine Sache, die für Java spezifisch ist, war , auf die Ingo hingewiesen hat ein Kommentar unten: Sie erhalten auch Grenzen beim Einchecken von Java, was den ohnehin langsameren Array-Zugriff noch langsamer macht ...

    
Ali 04.02.2014, 00:06
quelle
2

Ein vernünftigerer Maßstab wäre:

%Vor%

welches auf mein Intel Core Duo druckt (ja, es ist alt):

%Vor%

Wenn ich also sequentiell auf das Lookup-Array zugreife, wodurch die Anzahl der Cache-Misses minimiert wird und die Hotspot-JVM die Grenzen beim Array-Zugriff optimieren kann, ergibt sich eine leichte Verbesserung gegenüber einem Array von 1000 Elementen. Wenn wir einen zufälligen Zugriff auf das Array ausführen, verschwindet dieser Vorteil. Wenn die Tabelle größer ist, wird die Suche langsamer. Zum Beispiel für 10000 Elemente bekomme ich:

%Vor%

Also ist das Array-Lookup nicht schneller als die Multiplikation, es sei denn, das Zugriffsmuster ist (fast) sequentiell und das Lookup-Array ist klein.

In jedem Fall zeigen meine Messungen an, dass eine Multiplikation (und Addition) nur 4 Prozessorzyklen benötigt (2,3 ns pro Schleifeniteration auf einer 2 GHz CPU). Sie werden wahrscheinlich nicht viel schneller als das bekommen. Außerdem, wenn Sie nicht eine halbe Milliarde Multiplikationen pro Sekunde machen, sind die Multiplikationen nicht Ihr Flaschenhals, und die Optimierung anderer Teile des Codes wird ergiebiger sein.

    
meriton 04.02.2014 00:21
quelle

Tags und Links