PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Benchmark für Intels Loop Stream Detector?


Undertaker
2010-07-23, 14:30:12
Nein, ich meine Algorithmen, die sehr undurchschaubare Zugriffsmuster liefern. Da drehen die Intel-Chips Kreise um AMD. Mit Bandbreite hat das nichts zu tun, die kann eh nur ausgenutzt werden, wenn dies eben nicht der Fall ist.

Da hab ich neulich einen sehr interessanten Fall gehabt... Hab ein kleines Java-Programm geschrieben, dass Primzahlen berechnet (von 2 an in aufsteigender Reihenfolge, jede berechnete Primzahl kommt in eine ArrayList, die immer darauffolgende Zahl wird durch alle Elemente der ArrayList geteilt, im Falle einer Primzahl wieder in die Liste eingetragen usw). Kein Multithreading, keine weiteren Optimierungen. Beim Testen viel mir auf, das mein 2,93-3,06GHz Core i5 im Laptop Faktor 3(!) schneller ist als mein 3,5GHz Phenom II im PC...

Wäre das so ein Fall, wo der Loop Stream Detector den Unterschied macht? :confused:

Quellcode und Programm kann ich auch posten, wenn jemand Interesse hat.

Programm: Siehe Anhang

Am besten das aktuelle JDK (http://java.sun.com/javase/downloads/widget/jdk6.jsp)laden und installieren, dann braucht ihr nur noch die .bat Doppelklicken.

Coda
2010-07-23, 14:39:17
Gleiche JVM? 64 bit vs. 32 bit?

Undertaker
2010-07-23, 14:49:18
Exakt identisch, 64Bit. Wer Java drauf hat und mal testen will siehe Anhang. Einfach irgendwohin entpacken und die .bat starten, kurz warten und Zeit ablesen. Mein 3,5GHz Phenom 2 braucht (um die Zahlen 0-3.000.000 auf Primzahlen zu untersuchen) gut 4,5s, der ~2,93GHz i5 540M gut 1,5s.

Aktuelle Version siehe Startposting.

Coda
2010-07-23, 14:50:56
Das problem ist, dass Java erstmal alles kompiliere muss etc. Die Zeit die du da misst ist wohl nicht die, die du wirklich willst.

Undertaker
2010-07-23, 14:55:58
Ich bin zwar jetzt nicht der große Spezialist, aber meiner Vorstellung nach ist so eine .jar bereits fertig kompiliert, man benötigt nur das JRE samt nötiger Verknüpfung damit das Programm läuft. Das kompilieren selbst dauert auch kaum einen Wimpernschlag auf beiden Systemen von mir.

Wundert mich zumindest schon eine ganze Weile, warum der PII hier so deutlich unterlegen ist, der Code ist ja absolut trivial.

Coda
2010-07-23, 15:01:15
Java kompiliert in Bytecode, das ganze muss noch von der Runtime in x86 übersetzt werden. Und das dauert in diesem Fall wohl länger als alles andere.

Gib mir mal den Sourcecode.

Undertaker
2010-07-23, 15:06:50
Dann Gegenfrage, wenn dem so wäre wie du sagst (kann ich recht einfach testen, in dem ich die Zahl der zu untersuchenden Zahlen erhöhe): Warum sollte der i5 dann eben dabei soviel schneller sein? :confused:

Quellcode:


Nicht wundern, war eines meiner ersten Programme und ist sicherlich äußerst mies geschrieben. ;)

import java.util.ArrayList;
import java.lang.Math;

public class Primzahl3
{
private int zahl;
private int primzahl;
private int abbruch;
private int n;
private Integer intzahl;
private ArrayList<Integer> primzahlen;
private int wurzel;
private double zahld;
private long startzeit;
private long endzeit;
private boolean benchmark;

public Primzahl3()
{
zahl = 0;
n = 0;
primzahl = 0;
benchmark = false;
primzahlen = new ArrayList<Integer>();
}

public void berechnePrimZahlen(int max)
{
startzeit = System.currentTimeMillis();
zahl = 2;
while (zahl <= max) {
teste(zahl);
zahl++;
}
System.out.println(primzahlen.size() + " Primzahlen gefunden");
endzeit = System.currentTimeMillis();
System.out.println("Benötigte Rechenzeit: " + (endzeit - startzeit) + "ms");
primzahlen.clear();
}

private void teste(int zahlenwert)
{
n = 0;
abbruch = 0;
zahld = zahl;
wurzel = (int) Math.sqrt(zahld);
while ((abbruch == 0) && (n < primzahlen.size())) {
primzahl = primzahlen.get(n);
if ((zahlenwert % primzahl) == 0) {
ausgeben (false);
abbruch = 1;
}
else {
n++;
}
if (((primzahl > 4) && (n > wurzel)) || (zahl == 2)) {
ausgeben (true);
abbruch = 1;
}
}
if (abbruch == 0) {
ausgeben (true);
}
}

private void ausgeben(boolean ergebnis)
{
if (ergebnis == true) {
if (benchmark == false) {
System.out.println(zahl + ": Primzahl");
}
Integer intzahl = new Integer (zahl);
primzahlen.add(intzahl);
}
}

public void benchmarkStart()
{
System.out.println("Benchmark läuft, Primzahlen bis n=3.000.000 werden gesucht");
benchmark = true;
berechnePrimZahlen(3000000);
benchmark = false;
}

public static void main(String args[])
{
Primzahl3 primzahl3 = new Primzahl3();
primzahl3.benchmarkStart();
}
}

davidzo
2010-07-23, 15:24:36
Warum sollte der i5 dann eben dabei soviel schneller sein? :confused:

Speichersubsystem, Cache, SSD, Raid, Chipsatz? gibt da ne menge Möglichkeiten...

Allerdings stimme ich Coda da zu, ein Unterschied von dieser Größenordnung ist eher nicht in der CPU zu suchen sondern da limitiert etwas anderes massiv.

Coda
2010-07-23, 15:28:06
Dann Gegenfrage, wenn dem so wäre wie du sagst (kann ich recht einfach testen, in dem ich die Zahl der zu untersuchenden Zahlen erhöhe): Warum sollte der i5 dann eben dabei soviel schneller sein? :confused:
Ich will nur andere Faktoren ausschließen.

Ändert sich das Verhältnis wenn du die Grenze bis zu der berechnet wird änderst?

IVN
2010-07-23, 15:29:37
Speichersubsystem, Cache, SSD, Raid, Chipsatz? gibt da ne menge Möglichkeiten...

Allerdings stimme ich Coda da zu, ein Unterschied von dieser Größenordnung ist eher nicht in der CPU zu suchen sondern da limitiert etwas anderes massiv.
RAID, SSD und Chipsatz kann man da getrost ausschliessen. Spätestens nach dem 2. Ausführen spielen die keine Rolle mehr. Cache und MI können eine Rolle spielen, aber die sind ebenso "Teil' der CPU, wie die Ausführungseinheiten. Insofern liegt es doch an der CPU.

Undertaker
2010-07-23, 15:35:30
@Coda: Kaum. Für 0-10.000.000 Zahlen:

Phenom II 3,5GHz: 24,4s
Core i5 540M (2,93GHz): 7,8s

Bei 3M waren es:

Phenom II 3,5GHz: 4,6s
Core i5 540M (2,93GHz): 1,5s

Bleibt bei etwa Faktor 3. Der Leistungsunterschied entsteht also irgendwo in der Berechnungsschleife.

IVN
2010-07-23, 16:07:23
@Coda: Kaum. Für 0-10.000.000 Zahlen:

Phenom II 3,5GHz: 24,4s
Core i5 540M (2,93GHz): 7,8s

Bleibt bei etwa Faktor 3. Der Leistungsunterschied entsteht also irgendwo in der Berechnungsschleife.
D.h. bei deinem speziellen Code hat Nehalem eine 3 mal so hohe Pro-MHz-Leistung?

fdk
2010-07-23, 16:12:01
c2d @ 3.15ghz:
3m: 2746ms
Das Übersetzen des Bytecodes sollte bei dem Verhältnis von Codemenge zu durchlaufenen Iterationen keine Rolle spielen. Spaßeshalber könntest du ein zweites Array mit ein paar tausend Aufrufen von berechnePrimzahlen() füllen bevor du an die Zeitmessung mit dem eigentlichen Array gehst. Wenn ich die JVM-Doku noch Recht in Erinnerung habe sollte das aber keinen Unterschied machen da bei den neueren JVMs nichts redundant kompiliert wird.
€: Siehe: http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp bei 1500 liegt der threshold.

Undertaker
2010-07-23, 16:14:15
D.h. bei deinem speziellen Code hat Nehalem eine 3 mal so hohe Pro-MHz-Leistung?

Sofern bei meinem Phenom II nicht etwas völlig schief läuft - glaube ich nicht, auch mit einem K8-basierten Turion X2 kam ich taktbereinigt auf eine ähnliche Größenordnung - sieht das ganz so aus. Wobei man den obigen Code kaum sonderlich speziell nennen kann - ein paar Schleifen, eine ArrayList, Wurzel- und Modulo-Operationen. Da denkt man doch, man sollte keine sonderlichen architektonischen Unterschiede sehen. Soetwas kommt in jedem Programm vor... :confused:

@fdk:

Testen könnte ich bei Gelegenheit vieles mal: Sowohl die Wurzel- als auch Modulooperationen, aber auch den Listenzugriff... Irgendwo muss es da ja massive Differenzen geben. Interessant aber, dass auch dein Core 2 nicht so wirklich schnell ist, recht mittig zwischen PII und i5... Testest du nochmal die 10M Version? Siehe erstes Posting.

S940
2010-07-23, 16:31:52
Interessanter Test, da ignorier ich mal die Ignorliste :)

E8200 @3,4 GHz /FSB425 32bit Win2008:
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) Client VM (build 16.3-b01, mixed mode, sharing)

Ergebnis 10M:
~14sec. (variiert zw. 13,8 und 14,2)

Ergebnis 3M:
2,5s.

Ein P4 wäre jetzt vielleicht noch interessant.

@fdk:
Hattest Du 32 oder 64bit ?

ciao

Alex

fdk
2010-07-23, 16:45:20
Auf ein neues:

c2d (65nm) @3.15ghz, 64bit Win7

java version "1.6.0_21"
Java(TM) SE Runtime Environment (build 1.6.0_21-b06)
Java HotSpot(TM) Client VM (build 17.0-b16, mixed mode, sharing)


3m: 2.746 ms
10m: 15.070 ms

Undertaker
2010-07-23, 16:49:53
Bei zwei seperaten und recht übereinstimmenden Werten sollte das Core 2 Ergebnis eigentlich gesichert sein. Jetzt hätte ich gerne nochmal ein paar andere Werte von Nehalem/Lynnfield/Clarkdale Eignern sowie evntl. auch noch ein weiteres Phenom I/II Ergebnis.

IVN
2010-07-23, 16:54:58
Mein C2D@2.66GHz (2M) ist in 18 Sek fertig (10M).

Das Sys ist WinXP (32bit).

Mein C2D scheint trotz des kleineren Caches (2 vs 6 MB) und des deutlich langsameren FSBs (266 vs 425) schneller pro Takt zu sein, als S940's. O_o

Undertaker
2010-07-23, 17:05:29
Kleine Notiz am Rande: Hatte einen Mini-Fehler drin, wodurch er immer eine Primzahl zu viel gefunden hat - korrekt sind 216.816 bei 3M, 664579 bei 10M. Korrigiertes und neu hochgeladenes Paket für 3M und 10M im ersten Posting.

Die Benchmarkergebnisse sind davon unbeeinflusst!

@IVN: Pro Takt komme ich für 14s bei 3,4GHz und 18s bei 2,66GHz auf eine identische Leistung. Cache- und FSB scheinen hier keine sonderliche Bedeutung zu haben. Die Frage, was hier den Ausschlag gibt, steht nach wie vor. ;)

IVN
2010-07-23, 17:13:06
Kleine Notiz am Rande: Hatte einen Mini-Fehler drin, wodurch er immer eine Primzahl zu viel gefunden hat - korrekt sind 216.816 bei 3M, 664579 bei 10M. Korrigiertes und neu hochgeladenes Paket für 3M und 10M im ersten Posting.

Die Benchmarkergebnisse sind davon unbeeinflusst!

@IVN: Pro Takt komme ich für 14s bei 3,4GHz und 18s bei 2,66GHz auf eine identische Leistung. Cache- und FSB scheinen hier keine sonderliche Bedeutung zu haben. Die Frage, was hier den Ausschlag gibt, steht nach wie vor. ;)
(14-18)/18 = - 22% bei einem Anstieg des Taktes um 27,5 %


Dagegen der Vergleich zu fdk's CPU:

(15-18)/18 = -16,7% bei einem um 18,15% höheren Takt. DIe Werte sind also ungefähr da, wo man sie erwarten würd.

S940
2010-07-23, 17:20:40
Eventuell wären auch noch Linux Ergebnisse interessant. Manchmal ist die Win Speicherverwaltung kurios.

Gabs mal bei nem Boinc Programm. Unter Windows waren die AMDs (deutlich) schlecht, unter Linux plötzlich besser. Die Intels waren jeweils ungefähr gleich. Das Ganze konnte zu einer Unterschiedlichen Heap Behandlung verfolgt werden, wenn ich mich recht erinnere, aber ganz Genau kam nie raus, an was es wirklich lag.

Also falls jemand ne dual boot Umgebung hat ... bitte vorsichtshalber auch mal testen.

ciao

Alex

Undertaker
2010-07-23, 17:21:16
(14-18)/18 = - 22% bei einem Anstieg des Taktes um 27,5 %


Achtung, Rechenfehler. ;) Beispiel: 10s mit 1GHz, 5s mit 2GHz. Gleichschnell, richtig? Nach deiner Rechnung nicht: 100% mehr Takt, (5-10)/10 = -50% Leistung

Korrekte Rechnung:

18s/14s = 28,6% schneller
3,4GHz/2,66GHz = 27,8% Mehrtakt

Das passt.

AnarchX
2010-07-23, 17:21:56
Eine CPU mit 2,66GHz ist ~22% langsamer getaktet als eine mit 3,4GHz. Dem entsprechend ist die Pro-MHz-Leistung hier vergleichbar.
edit: Undertaker war früher dran.

IVN
2010-07-23, 17:27:51
Achtung, Rechenfehler. ;) Beispiel: 10s mit 1GHz, 5s mit 2GHz. Gleichschnell, richtig? Nach deiner Rechnung nicht: 100% mehr Takt, (5-10)/10 = -50% LeistungNein. +100% Takt, -50% Zeit. Das stimmt so.

Korrekte Rechnung:

18s/14s = 28,6% schneller
3,4GHz/2,66GHz = 27,8% Mehrtakt

Das passt.
SO kann man IMO nicht rechnen. Denn diese Rechnung würde implizieren, das die längere Zeit mehr Leistung bedeutet. Und schon gar nicht darf man so %e rechnen. Man muss die "Basis" abziehen um die %e ober-/unterhalb der 100% zu bekommen (mit dem "- Basis" fixiert man die 100%). Also entweder (18-14)/14 (für Punkte wie in 3dmark zB) oder (14-18)/18 für Zeiten.

Undertaker
2010-07-23, 17:39:27
Nein. +100% Takt, -50% Zeit. Das stimmt so.

Das ist schon korrekt, aber so kannst du nur schwer vergleichen. ;) Auch +28,6% Takt und -22% Zeit stimmt, nur erkennst du das erst, wenn du z.B. wie AnarchX mit dem Mindertakt der 2,66GHz CPU (~22%) ausgehst.

Wir sollten das jetzt hier auch nicht weiter breit treten - darum gehts nicht. Die Core 2 Werte passen und scheinen nicht auf Cache oder FSB anzusprechen. Wo wurde denn von der Core 2 auf die Nehalem-Architektur so heftig geschraubt, dass sich die Leistung in diesem Bereich etwa verdoppelt haben kann? :confused:

S940
2010-07-23, 17:49:45
So mir ist gerade noch eingefallen, dass ich noch ne alte OpenSolaris Installation hatte ...

Java ist etwas älter:
Java(TM) SE Runtime Environment (build 1.6.0_13-b03)
Java HotSpot(TM) Server VM (build 11.3-b02, mixed mode)

Dafür gibts diesmal 64bit Mode.

So und jetzt das Ergebnis:

Alex@opensolaris:~/Downloads$ java -jar Primzahl.jar
Benchmark läuft, Primzahlen bis n=10.000.000 werden gesucht
664580 Primzahlen gefunden
Benötigte Rechenzeit: 7934ms

Können 64bit soviel ausmachen ? Ich glaubs eher nicht ...

Edit: Mit expliziten 64bit Datentypen, sind nochmal ~400ms drin:

Alex@opensolaris:~/Downloads$ java -jar -d64 Primzahl.jar
Benchmark läuft, Primzahlen bis n=10.000.000 werden gesucht
664580 Primzahlen gefunden
Benötigte Rechenzeit: 7504ms


ciao

Alex

P.S: War noch die alte Prä-bugfix Jar.

IVN
2010-07-23, 17:57:51
Das ist schon korrekt, aber so kannst du nur schwer vergleichen. ;) Auch +28,6% Takt und -22% Zeit stimmt, nur erkennst du das erst, wenn du z.B. wie AnarchX mit dem Mindertakt der 2,66GHz CPU (~22%) ausgehst.Ja, du hast Recht. Trotzdem ist die Pro-Takt-Leistung bei den 3 C2Ds ein wenig unterschiedlich.

Auch wenn man wie von AnarchX vorgeschlagen rechnet...

s940's CPU:

(14-18)/18 = -22% Zeit, (2666 - 3400)/3400 = -21,6%

fdk's CPU:

(15-18)/18 = -16,7%, (2666 - 3150)/3150 = -15,4%

Auch mit deiner Methode...

18/14 = 28,6%, 3400/2666 = 27,5%

18/15 = 20%, 3150/2666 = 18,15%

Das impliziert dann schon, das s940's C2D ein wenig langsamer pro Takt ist.



Wir sollten das jetzt hier auch nicht weiter breit treten - darum gehts nicht. Die Core 2 Werte passen und scheinen nicht auf Cache oder FSB anzusprechen. Wo wurde denn von der Core 2 auf die Nehalem-Architektur so heftig geschraubt, dass sich die Leistung in diesem Bereich etwa verdoppelt haben kann? :confused:
Am IMC und dem dicken L3 scheint es nicht zu liegen. Denn wie du schon gesagt hast, haben Caches und FSB/IMC keinerlei EInfluss auf das Ergebnis.

Undertaker
2010-07-23, 18:13:50
Naja, diese Unterschiede von 28,6% zu 27,5% und 20% zu 18,15% sind doch locker im Bereich realistischer Messfehler - grundsätzlich reden wir ja hier über Differenzen von Faktor 2-3.

Viel interessanter finde ich die Linux Werte... Soviel schneller. :confused: Bei Gelegenheit, das wird allerdings erst nach meinen Prüdungen vermute ich, werd ich auch mal meine Schätzchen unter Ubuntu vermessen. Wenn Core i5 / PII dort allerdings genauso zulegen sollten wie es der Core 2 tut, hätte sich wenig geändert...

IVN
2010-07-23, 18:19:52
Ja, das ist echt eine krasse Leistungssteigerung.

Der_Korken
2010-07-23, 22:41:49
Ich sehe gerade, dass meine Ergebnisse sehr stark von den meisten hier genannten abweichen:

Core 2 Quad 9550 @ 3,3Ghz
Windows 7 64bit

3M: 1255ms
10M: 6793ms

Das ist zum Teil nur halbsoviel wie vergleichbare Dualcores hier im Thread schaffen. Am Betriebssystem kann es also auch nicht liegen, wie ein paar Posts über mir vermutet wurde. Irgendwas bewirkt auf manchen System eine Performanceverdopplung bzw -halbierung. Wenn man Wert des Phenom 2 halbieren würde, wären die Werte zumindest wieder halbwegs OK.

Jonny1983
2010-07-24, 00:14:56
XP-32Bit mit E8400 FSB jeweils 1600MHz

2,4GHz
3M: 3547ms
10M: 19078ms

mit 50% Mehrtakt

3,6GHz
3M: 2313ms
10M: 13156ms

S940
2010-07-24, 02:48:25
Ich sehe gerade, dass meine Ergebnisse sehr stark von den meisten hier genannten abweichen:

Core 2 Quad 9550 @ 3,3Ghz
Windows 7 64bit

3M: 1255ms
10M: 6793ms

Das ist zum Teil nur halbsoviel wie vergleichbare Dualcores hier im Thread schaffen. Am Betriebssystem kann es also auch nicht liegen, wie ein paar Posts über mir vermutet wurde. Irgendwas bewirkt auf manchen System eine Performanceverdopplung bzw -halbierung. Wenn man Wert des Phenom 2 halbieren würde, wären die Werte zumindest wieder halbwegs OK.
HMm naja ... kann schon noch am OS liegen .. vielleicht hättest Du bei Unix nochmal nur halb soviel.

Wobei ich mich frage, ob der Java Compiler Multicore unterstützen kann ... Deine Werte sind schon nicht schlecht, als Erklärung bleiben da erstmal nur die 4 Kerne ..

ciao

Alex

Undertaker
2010-07-24, 10:24:00
Schau dir doch den Quellcode an, das Programm ist zu 100% singlethreaded. Was soll der Compiler daran ändern können? Speculative multithreading? ;)

@Der_Korken:

Hast du zufällig noch ein anderes BS installiert, unter dem du mal testen kannst?

whatever
2010-07-24, 12:23:14
Ich habe hier einen c2d E8400 @default mit ondemand-governor (d.h. speedstep an)


Ubuntu 10.04, Kernel 2.6.32-24-generic x86_64 GNU/Linux
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01, mixed mode)

$ java -jar primzahl3.jar
Benchmark läuft, Primzahlen bis n=3.000.000 werden gesucht
216816 Primzahlen gefunden
Benötigte Rechenzeit: 1419ms

$ java -jar primzahl10.jar
Benchmark läuft, Primzahlen bis n=10.000.000 werden gesucht
664579 Primzahlen gefunden
Benötigte Rechenzeit: 7709ms

Undertaker
2010-07-24, 13:52:17
Hab doch mal schnell Ubuntu auf den PC gespielt (32Bit, 10.04):

3,5GHz Phenom II:

3M 5,2s
10M 29,1s

Sogar etwas langsamer als unter Windows... :confused:


xxx@xxx-desktop:~$ java -jar primzahl3.jar
Benchmark läuft, Primzahlen bis n=3.000.000 werden gesucht
216816 Primzahlen gefunden
Benötigte Rechenzeit: 5167ms
xxx@xxx-desktop:~$ java -jar primzahl10.jar
Benchmark läuft, Primzahlen bis n=10.000.000 werden gesucht
664579 Primzahlen gefunden
Benötigte Rechenzeit: 29107ms

S940
2010-07-24, 14:08:08
Test

64bit:
Alex@opensolaris:~/Downloads$ java -jar -d64 -Xprof Primzahl.jar
Benchmark läuft, Primzahlen bis n=10.000.000 werden gesucht
664580 Primzahlen gefunden
Benötigte Rechenzeit: 13171ms

Flat profile of 13,19 secs (387 total ticks): main

Interpreted + native Method
0,3% 0 + 1 java.lang.System.arraycopy
0,3% 1 + 0 java.util.ArrayList.clear
0,3% 1 + 0 Primzahl3.berechnePrimZahlen
0,8% 2 + 1 Total interpreted

Compiled + native Method
97,4% 377 + 0 Primzahl3.teste
1,8% 7 + 0 Primzahl3.berechnePrimZahlen
99,2% 384 + 0 Total compiled


Flat profile of 0,02 secs (1 total ticks): DestroyJavaVM

Thread-local ticks:
100,0% 1 Blocked (of total)


Global summary of 13,21 seconds:
100,0% 389 Received ticks
0,3% 1 Received GC ticks
--------------------------
32bit:
Alex@opensolaris:~/Downloads$ java -jar -d32 -Xprof Primzahl.jar
Benchmark läuft, Primzahlen bis n=10.000.000 werden gesucht
664580 Primzahlen gefunden
Benötigte Rechenzeit: 13579ms

Flat profile of 13,60 secs (410 total ticks): main

Interpreted + native Method
0,2% 1 + 0 Primzahl3.berechnePrimZahlen
0,2% 1 + 0 Total interpreted

Compiled + native Method
95,6% 392 + 0 Primzahl3.teste
4,1% 17 + 0 Primzahl3.berechnePrimZahlen
99,8% 409 + 0 Total compiled


Flat profile of 0,01 secs (1 total ticks): DestroyJavaVM

Thread-local ticks:
100,0% 1 Blocked (of total)


Global summary of 13,61 seconds:
100,0% 412 Received ticks
0,2% 1 Received GC ticks

--------------------------
Win32:
664580 Primzahlen gefunden
Ben÷tigte Rechenzeit: 34203ms

Flat profile of 34.22 secs (1194 total ticks): main

Interpreted + native Method
0.1% 1 + 0 java.util.ArrayList.ensureCapacity
0.1% 1 + 0 java.util.Arrays.copyOf
0.2% 2 + 0 Total interpreted

Compiled + native Method
99.2% 1184 + 0 Primzahl3.teste
0.4% 5 + 0 Primzahl3.berechnePrimZahlen
0.3% 3 + 0 Primzahl3.ausgeben
99.8% 1192 + 0 Total compiled


Flat profile of 0.01 secs (1 total ticks): DestroyJavaVM

Thread-local ticks:
100.0% 1 Blocked (of total)


Global summary of 34.23 seconds:
100.0% 1196 Received ticks

Undertaker
2010-07-24, 14:20:15
Alles was ich da erkennen kann ist, dass ~95-97% der Rechenzeit für die eigentliche Testschleife draufgehen :confused: - nunja, dass war zu erwarten, um z.B. die Zahlen bis 3.000.000 auf eine Primzahl zu untersuchen, sind in dieser ~262.000.000 Modulo-Operationen notwendig...
Die Prozentuale Verteilung ist auf dem PII genauso.

S940
2010-07-24, 14:27:27
Schau dir doch den Quellcode an, das Programm ist zu 100% singlethreaded. Was soll der Compiler daran ändern können? Speculative multithreading? ;)

Das heißt automatic vectorization:
http://en.wikipedia.org/wiki/Vectorization_%28computer_science%29

Anscheinend wird/wurde daran auch bei Java gearbeitet:
http://forums.java.net/jive/thread.jspa?threadID=18675

Das gibts entweder für SSE Code und/oder dann auch für multithreads.

Sollte man aber sehr einfach am Task Manager erkennen können.

@Der_Korken:
Kannst Du da mal bei Dir bitte nachschauen, was der Taskmanager macht ?

Wenn da nichts erkennbar ist, dann wars was Anderes. Unter Solaris läuft es bei mir auf alle Fälle auch nur mit 1 Thread.

Hab doch mal schnell Ubuntu auf den PC gespielt (32Bit, 10.04)
Hattest Du keine 64bit CD ? Bisher waren die meisten Ergebnisse doch 64bit wäre besser gewesen ;-)

Alles was ich da erkennen kann ist, dass ~95-97% der Rechenzeit für die eigentliche Testschleife draufgehen - nunja, dass war zu erwarten, um z.B. die Zahlen bis 3.000.000 auf eine Primzahl zu untersuchen, sind in dieser ~262.000.000 Modulo-Operationen notwendig...
Die Prozentuale Verteilung ist auf dem PII genauso.Jo, dachte man könnte vielleicht irgendwas zw. Solaris und Win erkennen .. aber nö, sieht ziemlich ähnlich aus.

Undertaker
2010-07-24, 14:49:18
Das wäre bei meiner Programmstruktur allerdings recht schwierig: Jede neu berechnete Primzahl wird in die ArrayList hinzugefügt, welche ich wiederum benötige, um die nächste Primzahl zu berechnen. Wenn man hier einfach anfängt parallel zu rechnen, kommt es sofort bei den ersten Zahlen zu Rechenfehlern, da nicht alle nötigen Divisoren getestet wurden - sie existieren schlicht noch nicht.
Zudem zeigt es ja wie erwähnt der Taskmanager: Auch auf meinem i5, der 10M in unter 8s schafft, läuft nur ein Thread.

S940
2010-07-24, 17:35:43
Zudem zeigt es ja wie erwähnt der Taskmanager: Auch auf meinem i5, der 10M in unter 8s schafft, läuft nur ein Thread.
Jo, bei mir ja auch, aber der i5 kann wieder wegen was anderem schneller sein. Am einfachsten ist erstmal, wenn Der_Korken nochmal kurz nachschaut.

Irgendwie glaub ichs auch nicht, aber was für ne Erklärung kann es sonst geben, dass ein Quad Core doppelt so schnell wie ein dual ist, wenn der Rest gleich ist ...

So oder so ziemlich merkwürdige Geschichten hier.

ciao

Alex

Twodee
2010-07-24, 19:52:02
Ich hab auch mal getestet:

Phenom2 940@3 Ghz - 1066DDR2 - Win7 Pro 64Bit

aktuellste 64Bit Java Engine

Q:\Primzahl_3M_10M>java -jar primzahl3.jar
Benchmark lõuft, Primzahlen bis n=3.000.000 werden gesucht
216816 Primzahlen gefunden
Ben÷tigte Rechenzeit: 5397ms

Q:\Primzahl_3M_10M>Pause
Drücken Sie eine beliebige Taste . . .

und


Q:\Primzahl_3M_10M>java -jar primzahl10.jar
Benchmark lõuft, Primzahlen bis n=10.000.000 werden gesucht
664579 Primzahlen gefunden
Ben÷tigte Rechenzeit: 30514ms

Q:\Primzahl_3M_10M>Pause
Drücken Sie eine beliebige Taste . . .

Der_Korken
2010-07-24, 19:52:03
Die CPU-Last liegt während der Berechnung bei etwa 26%, also ist es definitiv single-threaded.

Ich habe leider auf dem Rechner kein anderen Betriebssystem drauf, da ich den hauptsächlich zum zocken verwende und es sich für das bischen Arbeiten nicht lohnt, nach Alternativen zu suchen. Ich hätte höchstens noch einen E4300@1,8Ghz @WinXP 32bit als Zweitrechner im Angebot:

3M 4843ms
10M 26547ms

Der passt wieder deutlich besser ins Schema.

Edit:



...
[3M:] 5397ms
[10M:] 30514ms
...



:confused:

Was sind das denn für hohe Werte? Der ist ja jetzt sogar noch langsamer als mein alter Allendale mit Standardtakt. Langsam wundert mich hier gar nichts mehr.

Twodee
2010-07-24, 20:13:23
Die Werte passen doch zu Undertakers Phenom2 mit 3.5 Ghz.

pest
2010-07-24, 20:18:01
rückschlüsse auf die effizienz von microarchitekturen mit bytecode? na ich weiß nicht. das kann alle möglichen gründe haben.

Twodee
2010-07-24, 20:29:36
Gegentest auf Laptop (Core2Duo 45nm - 2MB Cache, 2Ghz - Win7 Pro - 32Bit)

D:\Downloads\NEW\Primzahl_3M_10M>java -jar primzahl3.jar
Benchmark lõuft, Primzahlen bis n=3.000.000 werden gesucht
216816 Primzahlen gefunden
Ben÷tigte Rechenzeit: 4299ms

D:\Downloads\NEW\Primzahl_3M_10M>Pause
Drücken Sie eine beliebige Taste . . .



bzw.


D:\Downloads\NEW\Primzahl_3M_10M>java -jar primzahl10.jar
Benchmark lõuft, Primzahlen bis n=10.000.000 werden gesucht
664579 Primzahlen gefunden
Ben÷tigte Rechenzeit: 24575ms

D:\Downloads\NEW\Primzahl_3M_10M>Pause
Drücken Sie eine beliebige Taste . . .

=Floi=
2010-07-24, 22:29:02
da sollte mal jemand einen eigenen thread aufmachen, worin es nur über die performance von java unter linux und windows geht. Das thema an sich ist nämlich auch sehr interessant!

winxp32bit
E5400@3,8ghz :D

3M 2250ms
10M 12141ms

wie man sieht skaliert der test nur mit dem takt :eek:

btw. es ist auch im 3dmark 06 schön zu sehen, dass der phenom 2 (ca. 15%) langsamer ist wie vergleichbare intel prozessoren. kannst du mal beim phenom 2 die stromsparmechanismen ausschalten?

G!ZMo
2010-07-24, 23:02:49
Hmm 64bit scheint zumindest unter OSX ganz schön was auszumachen. :eek:

macb00k:Primzahl_3M_10M alexr$ java -version
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02-279-10M3065)
Java HotSpot(TM) Client VM (build 16.3-b01-279, mixed mode)
macb00k:Primzahl_3M_10M alexr$ java -jar primzahl3.jar
Benchmark l?uft, Primzahlen bis n=3.000.000 werden gesucht
216816 Primzahlen gefunden
Ben?tigte Rechenzeit: 4506ms
macb00k:Primzahl_3M_10M alexr$ java -jar primzahl10.jar
Benchmark l?uft, Primzahlen bis n=10.000.000 werden gesucht
664579 Primzahlen gefunden
Ben?tigte Rechenzeit: 24167ms

macb00k:Primzahl_3M_10M alexr$ java -version
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02-279-10M3065)
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01-279, mixed mode)
macb00k:Primzahl_3M_10M alexr$ java -jar primzahl3.jar
Benchmark l?uft, Primzahlen bis n=3.000.000 werden gesucht
216816 Primzahlen gefunden
Ben?tigte Rechenzeit: 2948ms
macb00k:Primzahl_3M_10M alexr$ java -jar primzahl10.jar
Benchmark l?uft, Primzahlen bis n=10.000.000 werden gesucht
664579 Primzahlen gefunden
Ben?tigte Rechenzeit: 15783ms

MacBook 2,1: Core 2 Duo T7200 @ 2GHz, 2GB RAM, MacOS X 10.6.4

fdk
2010-07-24, 23:08:45
Will nicht wissen mit was für Steinzeit-JREs hier manche unterwegs sind ;).

S940
2010-07-25, 00:11:09
Will nicht wissen mit was für Steinzeit-JREs hier manche unterwegs sind .
Die CPU-Last liegt während der Berechnung bei etwa 26%, also ist es definitiv single-threaded.
Alles klar, danke.

Kannst Du noch Deine Java Version prüfen ? Das ist wohl recht wichtig. Wegen fdks Hinweis hab ich mir mal die neueste JAVA 7 Beta geholt:
java version "1.7.0-ea"
Java(TM) SE Runtime Environment (build 1.7.0-ea-b76)
Java HotSpot(TM) Client VM (build 17.0-b05, mixed mode, sharing)
http://download.java.net/jdk7/m5/

Ergebnis:
Benchmark lõuft, Primzahlen bis n=10.000.000 werden gesucht
664580 Primzahlen gefunden
Ben÷tigte Rechenzeit: 9077ms

Noch langsamer als unter Solaris, aber schon ein netter SpeedUp.
Eventuell liegt der restliche Unterschied an der Client/Server JRE. Weiss jemand, wo ich die Server JRE herbekomme ?
Naja vielleicht liegts ja auch ehn nur an 64bit..

aktuellste 64Bit Java Engine
Auch BETA 7, oder die letzte 6er JRE ?

ciao

Alex

Der_Korken
2010-07-25, 00:51:20
Gut, dass du nach der Version fragst. Ich hatte vor dem test die JRE 6 Update 17 drauf gehabt. Allerdings keine JDK, deswegen hab ich Undertakers Link benutzt und mir das JDK 6.21 installiert. Also Version 6.0.210.

Dummerweise hatte ich die alte JRE nicht deinstalliert und habe jetzt sowohl die alte, als auch die neue in der Systemsteuerung stehen. Funktionieren tut es aber tadellos. Ich werde die alte dann wohl mal entfernen und hoffen, dass es so bleibt.

huha
2010-07-25, 02:51:47
Du lernst ja gerade Java, also sind einige Hinweise angebracht. ;)
Erstens: Variablen, die du lokal brauchst, solltest du lokal deklarieren. Das macht das Programm übersichtlicher und die Variablen, die am Anfang der Klasse stehen, sind nur die wichtigen Variablen.
Zweitens: Nutze Methoden vernünftig. In deinem Code sind einige Stellen, die wirklich gruselig sind. Bei teste übergibst du zwar einen Parmeter, der wird aber fast nirgendwo benutzt, weil du lieber eine globale Variable verwendest. Das geht aktuell noch gut, macht den Code aber verwirrend und sollte nicht so gemacht werden.
Drittens: Der Algorithmus ist nicht so großartig, aber ich glaube nicht, daß es darum geht. ;)
Viertens: ArrayLists sind zwar schon ziemlich schnelle Listen, aber immer noch wesentlich lahmer als Arrays. Wenn du weißt, wieviele Elemente du haben wirst bzw. zumindest eine sinnvolle obere Grenze setzen kannst, dann lohnt sich ein Array mit einer Indexvariable, insbesondere bei primitiven Datentypen. Bei den Primzahlen geht das wundervoll, da du ja zumindest weißt, daß die meisten geraden Zahlen keine Primzahlen sind. Deine Liste braucht also maximal nur ungefähr halb so viele Einträge wie Zahlen, die du auf Primzahleigenschaft testen willst (Obacht, bei kleinen Zahlen stimmt das nicht ganz, aber da wir ziemlich viele Zahlen testen, ist uns das egal).
Wie du sehen wirst, gibt's mit einem Array statt einer Liste einen durchaus veritablen Geschwindigkeitsschub.
Man muß da natürlich aufpassen, daß man sich nicht zu viel Speicher krallt; aber bei 3 Millionen Zahlen ist unser Array (ich gehe mal davon aus, daß die Java-ints 32-bit-Integer sind, ich bin gerade zu faul um die Dokumentation zu lesen) 1.5 Millionen Einträge lang, also 1.5*4 = 6 MB, was absolut kein Problem für den Arbeitsspeicher ist.
Fünftens: Wenn du Benchmarks machst, mach mehrere und bau eine Funktion ein, die die Ergebnisse mittelt. Bei mir fluktuiert's zwar immer noch sehr stark, das liegt aber vielleicht daran, daß ich einen lahmen Rechner habe und den mit meinen Arbeiten nebenher gut genug auslaste.



import java.util.ArrayList;

import java.lang.Math;

public class Primzahl3 {
private int zahl;
private int primzahl;
private int n;
private static ArrayList<Integer> benchmarkResults;
private int[] primzahlen;
private int pctr = 0;

private int wurzel;
private long startzeit;
private long endzeit;
private boolean benchmark;

public Primzahl3() {
zahl = 0;
n = 0;
primzahl = 0;
benchmark = false;
primzahlen = new int[(3000000>>1) + 1];
}

public void berechnePrimZahlen(int max) {
startzeit = System.currentTimeMillis();
zahl = 2;
while (zahl <= max) {
teste(zahl);
zahl++;
}
System.out.println(pctr + " Primzahlen gefunden.");
endzeit = System.currentTimeMillis();
System.out.println("Benötigte Rechenzeit: " + (endzeit - startzeit) + "ms");
benchmarkResults.add((int) (endzeit - startzeit));
}

private void teste(int wert) {
n = 0;
wurzel = (int) (Math.sqrt(wert) + 0.5);
while (n < pctr) {
primzahl = primzahlen[(n>>1)];
if ((wert % primzahl) == 0) {
ausgeben(wert, false);
return;
}
else {
n++;
}
if (((primzahl > 4) && (n > wurzel)) || (wert == 2)) {
ausgeben(wert, true);
return;
}
}

ausgeben (wert, true);

}

private void ausgeben(int wert, boolean ergebnis) {
if (ergebnis == true) {
if (benchmark == false) {
System.out.println(wert + ": Primzahl");
}
primzahlen[pctr++] = wert;
}
}

public void benchmarkStart() {
System.out.println("Benchmark läuft, Primzahlen bis n=3.000.000 werden gesucht");
benchmark = true;
berechnePrimZahlen(3000000);
}

public static void main(String args[]) {
benchmarkResults = new ArrayList<Integer>();
Primzahl3 primzahl3;
for (int i = 0; i < 10; i++) {
primzahl3 = new Primzahl3();
primzahl3.benchmarkStart();
primzahl3 = null;
}

int avg = 0;
for (int i : benchmarkResults) {
avg = avg + i;
}
avg = (int) (((double) avg) / benchmarkResults.size());
System.out.println("Durchschnittlich benötigte Rechenzeit (10 Durchläufe): " + avg + " ms");
}
}





Meine Version ist angehängt.

-huha

Twodee
2010-07-25, 10:17:24
@Huha

Ist ja nett gemeint aber es ändert nichts am Ausgangsproblem. Die Frage bleibt ;)

S940
2010-07-25, 10:22:05
Ist ja nett gemeint aber es ändert nichts am Ausgangsproblem. Die Frage bleibt ;)Kannst Du bei Gelegenheit nochmal mit der 64bit 1.7er nachtesten (http://download.java.net/jdk7/m5/), oder war die schon drauf ?

PatkIllA
2010-07-25, 10:38:22
Viertens: ArrayLists sind zwar schon ziemlich schnelle Listen, aber immer noch wesentlich lahmer als Arrays. Wenn du weißt, wieviele Elemente du haben wirst bzw. zumindest eine sinnvolle obere Grenze setzen kannst, dann lohnt sich ein Array mit einer Indexvariable, insbesondere bei primitiven Datentypen. Bist du sicher dass das nicht am Boxing liegt? Eine ArrayList macht nichts anderes als die Werte in ein Array zu schreiben und bei Bedarf in ein neues Array zu kopieren. Die Anfangskapazität kann man auch festlegen.

Außerdem ist die Typsicherheit von Arrays in vielen Sprachen broken by Design:
http://blogs.msdn.com/b/ericlippert/archive/2007/10/17/covariance-and-contravariance-in-c-part-two-array-covariance.aspx

Twodee
2010-07-25, 10:38:23
@Alex
Nein, es war die aktuellste 6er Version installiert, extra für den test runtergeladen und installiert.
Kann später (wenn ich an den PC darf :rolleyes:) aber mit der 7er nachholen.

S940
2010-07-25, 10:50:14
@Alex
Nein, es war die aktuellste 6er Version installiert, extra für den test runtergeladen und installiert.
Kann später (wenn ich an den PC darf :rolleyes:) aber mit der 7er nachholen.
Alles klar, danke. Damit wären wir zumindest dann mal auf nem einheitlichen Stand. Ich hoffe Der_Korkens C2Q ist nicht nochmal doppelt so schnell :freak:

@Der_Korken:
Kannst Du eventuell auch mal mit der 1.7er nachtesten ?

merci

Alex

Undertaker
2010-07-25, 11:11:31
btw. es ist auch im 3dmark 06 schön zu sehen, dass der phenom 2 (ca. 15%) langsamer ist wie vergleichbare intel prozessoren. kannst du mal beim phenom 2 die stromsparmechanismen ausschalten?

War im 3,5GHz Setting alles deaktiviert.

@Huha:

Danke für die Tipps. ;) Vieles hätte ich mittlerweile auch schon erheblich anders gemacht, die Grundzüge des Programms habe ich schon vor etwa 4 Monaten geschrieben... Letzte Woche dann mein eigentliches Projekt, einen Logik-Simulator für verschiedene Gattertypen inkl. Einlesen einer Schaltungs- und einer Eventdatei vollendet. :freak:

Bei Gelegenheit werde ich sicher nochmal eine saubere Version schreiben (in der ich auch versuche Multithreading zu implementieren), aber das eigentlich interessante sind ja nach wie vor die Performanceunterschiede zwischen verschiedenen Architekturen hier...

Demogod
2010-07-25, 11:23:34
aber dann schreib es doch direkt in c oder c++ (or whatever fits best) damit du und andere es für andere target platformen durch den gcc/llvm/clang jagen können..

Twodee
2010-07-25, 12:10:22
Gegentest auf Laptop (Core2Duo 45nm - 2MB Cache, 2Ghz - Win7 Pro - 32Bit)

D:\Downloads\NEW\Primzahl_3M_10M>java -jar primzahl3.jar
Benchmark lõuft, Primzahlen bis n=3.000.000 werden gesucht
216816 Primzahlen gefunden
Ben÷tigte Rechenzeit: 4299ms

D:\Downloads\NEW\Primzahl_3M_10M>Pause
Drücken Sie eine beliebige Taste . . .



bzw.


D:\Downloads\NEW\Primzahl_3M_10M>java -jar primzahl10.jar
Benchmark lõuft, Primzahlen bis n=10.000.000 werden gesucht
664579 Primzahlen gefunden
Ben÷tigte Rechenzeit: 24575ms

D:\Downloads\NEW\Primzahl_3M_10M>Pause
Drücken Sie eine beliebige Taste . . .

mit Beta7:


D:\Downloads\NEW\Primzahl_3M_10M>java -jar primzahl3.jar
Benchmark lõuft, Primzahlen bis n=3.000.000 werden gesucht
216816 Primzahlen gefunden
Ben÷tigte Rechenzeit: 2838ms

D:\Downloads\NEW\Primzahl_3M_10M>Pause
Drücken Sie eine beliebige Taste . . .
bzw.

D:\Downloads\NEW\Primzahl_3M_10M>java -jar primzahl10.jar
Benchmark lõuft, Primzahlen bis n=10.000.000 werden gesucht
664579 Primzahlen gefunden
Ben÷tigte Rechenzeit: 15342ms

D:\Downloads\NEW\Primzahl_3M_10M>Pause
Drücken Sie eine beliebige Taste . . .

nice. fast Faktor 2. und was die schwankung betrifft: ~10ms im 3M Test.

Der_Korken
2010-07-25, 12:39:47
@Der_Korken:
Kannst Du eventuell auch mal mit der 1.7er nachtesten ?


Hat sich nichts geändert bei mir:

3M: 1298 ms
10M: 6606 ms

Es schwankt allerdings stärker als vorher. Beim 10M hatte ich bei 5 Durchläufen 2x ~6500ms, 1x ~6600ms und 2x ~7000ms. Bei etwa 50% der Testläufe sind es um die 6600ms, bei den anderen 50% um die 7100ms. Der 3M ist sehr konstant.

S940
2010-07-25, 13:52:44
Ok Danke Euch beiden, da haben wir also dann mittlerweile bei 10M folgendes Bild:

C2Q@3,3 GHz/64bit: 6606 ms (Der_Korken)
C2D@3,4 GHz/32bit: 9077 ms (ich)
C2D@2,0 Ghz 32Bit: 15342ms (Twodee)

Ich hoffe mal der Unterschied zw. mir und Der_Korken geht aufs 32<>64bit Konto.
Die Ungereimtheiten wären damit gelöst, aber vom Sachverhalt wären wir wieder beim Anfang, die Intels sind doppelt so schnell.

Mal schauen, was Undertaker noch mit seinem i5 rausholen kann ;-)

Weiteres Tests sind erwünscht, z.B: AMD K8 oder Dualcore K10 mit 1MB L2 (vielleicht macht bei AMD der L2 was aus), oder auch ein alter P4 wäre sicher lustig. Bitte aber die 1.7Beta JVM installieren. Hier nochmal der Link:
http://download.java.net/jdk7/m5/

ciao

Alex

Twodee
2010-07-25, 14:40:46
@Alex. ich habe den Ph2 mit Java7 noch nicht vermessen, der obrige Post enthält nicht umsonst den Quote des Core2Duo Java 6 Durchlaufs.
Mit anderen Worten die 15 Sekunden stammen vom 2Ghz Core2Duo Notebook.

S940
2010-07-25, 15:36:26
@Alex. ich habe den Ph2 mit Java7 noch nicht vermessen, der obrige Post enthält nicht umsonst den Quote des Core2Duo Java 6 Durchlaufs.
Mit anderen Worten die 15 Sekunden stammen vom 2Ghz Core2Duo Notebook.
AH oops, alles klar.
Hatte ich übersehen, sorry ;-)

Twodee
2010-07-25, 16:04:15
Phenom2 940@3 Ghz - 1066DDR2 - Win7 Pro 64Bit

aktuellste 64Bit Java Engine

Q:\Primzahl_3M_10M>java -jar primzahl3.jar
Benchmark lõuft, Primzahlen bis n=3.000.000 werden gesucht
216816 Primzahlen gefunden
Ben÷tigte Rechenzeit: 5397ms

Q:\Primzahl_3M_10M>Pause
Drücken Sie eine beliebige Taste . . .

und


Q:\Primzahl_3M_10M>java -jar primzahl10.jar
Benchmark lõuft, Primzahlen bis n=10.000.000 werden gesucht
664579 Primzahlen gefunden
Ben÷tigte Rechenzeit: 30514ms

Q:\Primzahl_3M_10M>Pause
Drücken Sie eine beliebige Taste . . .





Phenom2 940@3 Ghz - 1066DDR2 - Win7 Pro 64Bit

aktuellste 64Bit Java Engine 7 Beta

Q:\Primzahl_3M_10M>java -jar primzahl3.jar
Benchmark lõuft, Primzahlen bis n=3.000.000 werden gesucht
216816 Primzahlen gefunden
Ben÷tigte Rechenzeit: 5415ms

Q:\Primzahl_3M_10M>Pause
Drücken Sie eine beliebige Taste . . .

und


Q:\Primzahl_3M_10M>java -jar primzahl10.jar
Benchmark lõuft, Primzahlen bis n=10.000.000 werden gesucht
664579 Primzahlen gefunden
Ben÷tigte Rechenzeit: 30614ms

Q:\Primzahl_3M_10M>Pause
Drücken Sie eine beliebige Taste . . .




Windows Enerie-Optionen war auf "höchste Performance" eingestellt

S940
2010-07-25, 16:28:45
Lol, also 0 Unterschied ?
Suupie .. da sind wir dann fast beim Faktor 4.
Wie war der Speicher eingestellt ? Ganged/Unganged ? Falls möglich, und wenn es Dir noch was wert ist, teste mal bitte noch mit Ganged.

Eigentlich sollte das Ganze ja FSB/RAM/IO unabhängig sein, aber rein zur Vorsicht ;-)

ciao

Alex

Twodee
2010-07-25, 16:48:54
Also ich hab spasseshalber mal single-channel getestet, war genauso so langsam/schnell wie dual-channel unganged. Der Core2Duo war übrigends nur single channel.

S940
2010-07-25, 17:11:00
Also ich hab spasseshalber mal single-channel getestet, war genauso so langsam/schnell wie dual-channel unganged. Der Core2Duo war übrigends nur single channel.
Also kein dual channel ganged ? Frag nur, da es bei DDR2 mit ganged besser ist den Cache zu füllen, da bei ganged das Verhältnis zu den Cache-Lines optimal ist. Die 64bit Version verbraucht immerhin um die ~25MB RAM, vielleicht machts ein bisschen was aus .. keine Ahnung.
Single channel bringt natürlich keine Besserung ^^

Coda
2010-07-25, 17:58:43
Bei Java ist halt immer das Problem, dass man nicht weiß was im Endeffekt ausgeführt wird.

Ich übertrag beizeiten das ganze mal in C++ und dann sehen wir ob die Resultate die gleichen sind.

Demogod
2010-07-25, 18:09:24
Danke das wollte ich hören :)

fdk
2010-07-25, 18:14:07
Also kein dual channel ganged ? Frag nur, da es bei DDR2 mit ganged besser ist den Cache zu füllen, da bei ganged das Verhältnis zu den Cache-Lines optimal ist. Die 64bit Version verbraucht immerhin um die ~25MB RAM, vielleicht machts ein bisschen was aus .. keine Ahnung.
Single channel bringt natürlich keine Besserung ^^

Hast du das aus dem Taskmanager? Dort siehst du nur was die JVM sich reserviert. Um zu sehen was die Anwendung benötigt brauchst du zB. jConsole /jVisualVM aus dem JDK. Leider ist das nicht wirklich für solche µApps gedacht.

e sagt:
jdk7 beta 64bit@ Allendale e6300@3.15ghz: ziemlich genau 2000ms für 3m.

S940
2010-07-25, 18:33:19
Hast du das aus dem Taskmanager? Dort siehst du nur was die JVM sich reserviert. Um zu sehen was die Anwendung benötigt brauchst du zB. jConsole aus dem JDK. Leider ist das nicht wirklich für solche µApps gedacht.

Jein, hab unter Solaris mit den Xmx /Xms Kommandos experimentiert, mit 32bit lief mit XMX/XMS = 16MB alles wunderbar, bei 64bit gabs nen Fehler. Bei 20MB gabs keinen Fehler, aber das Ding lief ewig .. hat wahrscheinlich immer schön speicher freigeschaufelt und neu belegt :freak:

Ab ~25MB liefs dann wieder normal durch.

Aber gut, das war dann auch wieder nur die komplette JVM.

@Coda:
Gute Idee, Thx :)

ciao

Alex

Coda
2010-07-25, 19:03:43
Ich hab mir erlaubt das Ganze dabei gleich ein wenig aufzuräumen.

#include <iostream>
#include <vector>
#include <boost/progress.hpp>

static std::vector<double> benchmarkResults;
static int primzahlen[(3000000/2) + 1];
static int pctr;

void teste(int wert)
{
int wurzel = (int)(sqrt(double(wert)) + 0.5);
int n = 0;

while(n < pctr) {
int primzahl = primzahlen[n / 2];

if((wert % primzahl) == 0) {
return;
}
else {
++n;
}

if((primzahl > 4 && n > wurzel) || wert == 2) {
primzahlen[pctr++] = wert;
return;
}
}

primzahlen[pctr++] = wert;
}

void berechnePrimZahlen(int max)
{
boost::progress_timer t;

int zahl = 2;
while(zahl <= max) {
teste(zahl);
++zahl;
}

std::cout << pctr << " Primzahlen gefunden." << std::endl;

benchmarkResults.push_back(t.elapsed());
}

void benchmarkStart()
{
pctr = 0;

std::cout << "Benchmark laeuft, Primzahlen bis n=3.000.000 werden gesucht" << std::endl;
berechnePrimZahlen(3000000);
}

int main()
{
for(int i=0; i<10; ++i) {
benchmarkStart();
}

double avg = 0;
for(unsigned int i=0; i<benchmarkResults.size(); ++i) {
avg = avg + benchmarkResults[i];
}
avg = (avg / double(benchmarkResults.size())) * 1000.0;

std::cout << "Durchschnittlich benoetigte Rechenzeit (10 Durchlaeufe): " << avg << " ms" << std::endl;

std::cin.ignore();
std::cin.get();
}

Bei mir gibt es praktisch keinen Unterschied zur Java-Variante. Braucht beides 1,5s pro Durchlauf.

fdk
2010-07-25, 19:17:43
Same here. Braucht 2ms länger als die Java-Variante. (2002ms) Dh. die Abweichung liegt im Promillebereich.
jdk7 beta 64bit@ Allendale e6300@3.15ghz: ziemlich genau 2000ms für 3m.

Der_Korken
2010-07-25, 19:19:20
Bei dem C++ Programm komme ich auf 1147,2 ms nach den 10 Durchläufen. Es ist also sogar noch einiges schneller als das Java-Programm.

Coda
2010-07-25, 19:41:23
Also laut VTune ist bei mir der Performance-Fresser die Instruction die testet ob ((wert % primzahl) == 0). Ich vermute die muss jedes Mal auf die Division warten.

Da ich aber leider keinen Phenom habe weiß ich nicht was dort passiert. Der LSD hat wohl aber nichts mit dem Performancevorteil zu tun.

Undertaker
2010-07-25, 19:47:51
Da scheinen sich Java und C nicht viel zu nehmen, ich vermute mal die Performancevorteile kommen nur durch durch Codas "Entschlackung".

Core i5 540M (2,93GHz):
Meine Version, Java 1.7: 1,42s
Codas Version, C(++?): 1,27s

Phenom II X4 940 (3,5GHz)
Meine Version, Java 1.6: 4,5s

Phenom II X4 955 (3,3GHz, von einem Kumpel)
Codas Version, C(++?): 4,35s

Turion X2 (2,0GHz):
Codas Version, C(++?): 7,25s

Der Core 2 scheint nach Der_Korken recht ähnlich schnell zu sein wie der Core i5, nur der Phenom II und der K8 (pro Takt identisch schnell!) fallen ab. :confused:

Coda
2010-07-25, 19:53:08
Meine Vermutung ist, dass idiv (für das Modulo) bei AMD eine Vector-Instruction ist - und daran hängt der ganze Benchmark. Ich schau das gerade nach.

Das ist für normale Anwendungen aber total unrealistisch, das kann ich dir schonmal sagen.

Coda
2010-07-25, 19:56:57
Ne ist keine Vector-Instruction. Aber bei einem Nahalem ist die Division trotzdem fast doppelt so schnell wie bei einem K10. Das könnte die Sache erklären.

Aber wie gesagt, ohne Profiling mit einem K10 kann ich das nicht genau sagen.

hq-hq
2010-07-25, 20:03:15
904.3ms @i5 4200mhz und codas zip (windoof7 32bit)
ich hab noch einen alten athlon x2 mit 2,7ghz rumstehen, könnte ein nt einbauen und laufen lassen...

S940
2010-07-25, 20:09:34
Hmm vielleicht der Fast Radix-16 Divider ?
Läuft Modulo auch über den ?

Wenn ich mich recht erinnere, dann gibts den aber erst ab 45nm also Wolfdale/Penryn, die 65nm sollten dann etwas langsamer sein.

Bei mir braucht es 1.134ms.

@Coda:
Sollte bei dem kleinen Proggi überflüssig sein, aber vorsichtshalber noch die Frage: Welcher Compiler und welche Optimierungsstrings ? :)

ciao

Alex

Coda
2010-07-25, 20:11:52
VC++ 2010, volle Optimierungen, SSE2, 32 bit

Twodee
2010-07-25, 20:12:59
Q9650@4203 Mhz (Win7-64Bit) ~ 898 ms ;D

Coda
2010-07-25, 20:17:49
Hmm vielleicht der Fast Radix-16 Divider ?
Ja, das habe ich mir auch schon gedacht. Kann das ganze mal jemand auf einem Conroe testen?

Läuft Modulo auch über den ?
Sicher.

Edit: Ein Pentium 4 dürfte auch ziemlich abkacken. Hat das noch jemand einen rumstehen?

Der_Korken
2010-07-25, 20:26:49
Ja, das habe ich mir auch schon gedacht. Kann das ganze mal jemand auf einem Conroe testen?


Mein Allendale@1,8Ghz braucht bei deinem Programm 3463,9ms. Wenn ich das taktbereinigt in Verhältnis zu meinem C2Q setze, ergibt sich ein Geschwindigkeitsvorteil von Faktor 1,65 für letzteren. Ich muss aber dazu sagen, dass der Allendale unter XP 32bit läuft, statt Win7 64bit. Das relativiert die Ergebnisse vielleicht, da überlass ich die Einschätzung dir.

Coda
2010-07-25, 20:29:18
32 oder 64 bit Windows spielt keinen Rolle. Damit dürfte die Sache auch geklärt sein. Das ist mehr als signifikant.

Coda
2010-07-25, 20:41:24
Da scheinen sich Java und C nicht viel zu nehmen, ich vermute mal die Performancevorteile kommen nur durch durch Codas "Entschlackung".
Nö. Die haben keinen Einfluss auf die Performance. C++ ist so schneller. Wenn ich Profile Guided Optimizations benutze sogar nochmal deutlich mehr.

Allerdings ändert das nichts daran, dass es an der Division hängt.

Der_Korken
2010-07-25, 20:45:34
Der Q6600@2,4Ghz von meinem Freund braucht 2701,5ms. Das macht noch mal einen Faktor von 1,71 zu meinem C2Q. Das bestätigt nur das, was ich oben schon gepostet habe. Damit ist der Wert nochmal abgesichert.

Undertaker
2010-07-25, 20:49:35
Dann wäre das Mysterium ja gelöst. :) Bleibt nur noch eine Frage: Ist Modulo in der Praxis eine so seltene Operation, dass dies praktisch keine größere Bedeutung hat? :confused:

Coda
2010-07-25, 20:51:59
In der Praxis macht man ja noch andere Sachen als auf eine Division zu warten. CPUs können Out-Of-Order ja sogar schon Instructions danach ausführen solang sie unabhängig sind. Zudem wartet man oft genug einfach auf den Speicher oder Cache.

Das ganze ist also höchst synthetisch.

Wuge
2010-07-25, 22:36:27
4 GHz i7: 1391.3

Pentium 965 XE (Dual Netburst mit HT, @ 3.2 GHz auf Server 2008 R2 x64): 4311.2

Man möge das deuten ;)

EDIT: Mein Netburst-Schätzchen haut den Phenom II? Yeah. Ich wusste schon immer, dass es irgendetwas gibt, das der P4 kann ;)

Tiamat
2010-07-26, 00:32:46
Die Modulo-Operation ist in dem Ausmaß halt sehr teuer.
Mein Mac mini benötigt mit deinem Programm für 10M 40sek.
Mit dem Sieb des Erathotenes lediglich 700ms.

Mein Vorschlag wäre das ganze mal in long oder BigInteger zu machen, da haben die CPUs wenigstens was zu rechnen. Natürlich müsste hier der Heap-size erhöht werden.

Gruß
Tiamat

Coda
2010-07-26, 00:42:29
Das würde aber wohl nichts an den Verhältnissen ändern. Eine 64-Bit-Division ist mit Radix-16 auch schneller und ein BigInteger-Modulo ist auch nur durch viele Divisionen implementiert.

Tiamat
2010-07-26, 07:15:02
Schon klar, aber man kann Primzahlen auch ohne Div oder Modulo berechnen.
So gesehen liegt dann ein Intel Atom mit der Variante gleichauf mit einem Phenom II seines Programmes ;D.

Sowas wie wer findet die größte Primzahl in n Minuten fänd ich viel sinniger, da man somit halbwegs ne HPC-Anwendung simuliert, die früher tatsächlich von Supercomputern durchgeführt wurde, wo dann solche Spielereien (http://www.spiegel.de/wissenschaft/mensch/0,1518,443817,00.html)rausgekommen sind.

Twodee
2010-07-26, 07:57:30
Wäre denn die Variante ohne Div/Modulo schneller?

S940
2010-07-26, 09:43:52
Wäre denn die Variante ohne Div/Modulo schneller?
Anzunehmen, die DIV Unit ist bei den CPUs immer am langsamsten. Am Besten ist es immer, sie nicht zu benutzen ;-)

Tiamat
2010-07-26, 10:04:30
Den Vergleich mit dem Atom und dem Phenom II hab ich nicht umsonst erwähnt ;D

Twodee
2010-07-26, 10:29:01
Anzunehmen, die DIV Unit ist bei den CPUs immer am langsamsten. Am Besten ist es immer, sie nicht zu benutzen ;-)
Ok, dann schreibt das Programm. Bin gespannt welche Variante schneller ist ;)

Sie nicht zu benutzen würde sich in dem Fall auf nicht Fast Radix 16 fähige CPUs beschränken :rolleyes:

S940
2010-07-26, 12:58:45
Ok, dann schreibt das Programm. Bin gespannt welche Variante schneller ist ;)
Hat Tiamat doch schon gemacht:
Die Modulo-Operation ist in dem Ausmaß halt sehr teuer.
Mein Mac mini benötigt mit deinem Programm für 10M 40sek.
Mit dem Sieb des Erathotenes lediglich 700ms.

Anderer Algo ohne Mod / Div -> große Wirkung.
Sie nicht zu benutzen würde sich in dem Fall auf nicht Fast Radix 16 fähige CPUs beschränken :rolleyes:Ne, Tiamats Progrämmchen wäre auch auf einer Radix16 CPU schneller. Wie besagt DIV ist teuer. Alles andere dagegen ist ein Klacks ;-)

Tiamat
2010-07-26, 13:07:12
Hier ist der Source.
Einfach entpacken, mit javac Sieb.java kompilieren und mit java Sieb ausführen.

Gruß
Tiamat

Twodee
2010-07-26, 14:14:03
Hat Tiamat doch schon gemacht:

Anderer Algo ohne Mod / Div -> große Wirkung.
Ne, Tiamats Progrämmchen wäre auch auf einer Radix16 CPU schneller. Wie besagt DIV ist teuer. Alles andere dagegen ist ein Klacks ;-)
Er verwendet einen anderen Algo. Ich bezog mich auf den original Algo, allerdings ohne direkte Verwendung von Div/Modulo.

MikeB
2010-07-26, 16:36:28
Ich hab mir erlaubt das Ganze dabei gleich ein wenig aufzuräumen.


Darf ich noch anmerken dass in dem algo 2 integerdivisionen sind?
einmal das modulo
und auch noch "int primzahl = primzahlen[n / 2];"
da n signed ist, darf der compiler keinen rechtshift daraus machen.

Michael

S940
2010-07-26, 17:39:27
Er verwendet einen anderen Algo. Ich bezog mich auf den original Algo, allerdings ohne direkte Verwendung von Div/Modulo.
Und wie willst Du das anstellen ? Der Algo basiert auf modulo, das bekommst Du nicht weg.

Das beste der Gefühle ist sowas hier:

int zahl1 = 11;
int zahl2 = 4;
int rest; rest = zahl1 - ((zahl1 / zahl2) * zahl2)

Aber das wird sicher auch nicht viel helfen, da man ne Mod Funktion gegen MUL+DIV+ADD eintauscht ...

Coda
2010-07-26, 18:00:18
Darf ich noch anmerken dass in dem algo 2 integerdivisionen sind?
einmal das modulo
und auch noch "int primzahl = primzahlen[n / 2];"
da n signed ist, darf der compiler keinen rechtshift daraus machen.
Verdammt, das hab ich übersehen. Ich hab zur Klarheit n/2 draus gemacht, aber nicht bedacht, dass int falsch ist. Ich bin davon ausgegangen, dass er sowieso einen Shift verwendet.

Die Änderung aller ints zu unsigned bringt 200ms bei der Suche bis 3 Mio. Dadurch wird wohl auch der Abstand zwischen AMD und Intel kleiner werden.