Warum dieser Java-code nicht nutzen, alle CPU-Kerne?
Den beigefügten einfache Java-code laden sollten alle verfügbaren cpu-Kern ab, wenn es mit den richtigen Parametern. So zum Beispiel, starten Sie es mit
java VMTest 8 int 0
start 8 threads, die nichts anderes tun, als die Schleifen und das hinzufügen von 2 auf eine ganze Zahl. Etwas, das läuft in Registern und auch nicht reserviert neuen Speicher.
Das problem, das wir heute gegenüberstehen, ist, dass wir nicht bekommen, ein 24-core-Maschine geladen (AMD 2 sockets, 12 Kerne), die beim ausführen dieser einfachen Programm (mit 24 threads natürlich). Ähnliche Dinge passieren, mit 2 Programme zu je 12 Fäden oder kleinere Maschinen.
So unser Verdacht ist, dass die JVM (Sun JDK 6u20 auf Linux x64) nicht gut skalieren.
Hat sonst noch jemand ähnliches oder hat die Fähigkeit zu laufen und zu berichten, ob oder nicht es läuft auch gut auf seine/Ihre Maschine (>= 8 Kerne nur bitte)? Ideen?
Habe ich versucht, die auf Amazon EC2 mit 8 cores auch, aber die virtuelle Maschine scheint zu laufen unterscheidet sich von einem realen Feld, so dass das laden verhält sich Total seltsam.
package com.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class VMTest
{
public class IntTask implements Runnable
{
@Override
public void run()
{
int i = 0;
while (true)
{
i = i + 2;
}
}
}
public class StringTask implements Runnable
{
@Override
public void run()
{
int i = 0;
String s;
while (true)
{
i++;
s = "s" + Integer.valueOf(i);
}
}
}
public class ArrayTask implements Runnable
{
private final int size;
public ArrayTask(int size)
{
this.size = size;
}
@Override
public void run()
{
int i = 0;
String[] s;
while (true)
{
i++;
s = new String[size];
}
}
}
public void doIt(String[] args) throws InterruptedException
{
final String command = args[1].trim();
ExecutorService executor = Executors.newFixedThreadPool(Integer.valueOf(args[0]));
for (int i = 0; i < Integer.valueOf(args[0]); i++)
{
Runnable runnable = null;
if (command.equalsIgnoreCase("int"))
{
runnable = new IntTask();
}
else if (command.equalsIgnoreCase("string"))
{
runnable = new StringTask();
}
Future<?> submit = executor.submit(runnable);
}
executor.awaitTermination(1, TimeUnit.HOURS);
}
public static void main(String[] args) throws InterruptedException
{
if (args.length < 3)
{
System.err.println("Usage: VMTest threadCount taskDef size");
System.err.println("threadCount: Number 1..n");
System.err.println("taskDef: int string array");
System.err.println("size: size of memory allocation for array, ");
System.exit(-1);
}
new VMTest().doIt(args);
}
}
InformationsquelleAutor der Frage ReneS | 2010-05-19
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich nicht sehen, nichts falsch mit Ihrem code.
Aber, leider, können Sie nicht angeben, die Prozessor-Affinität in Java. Also, das ist eigentlich Links bis zu dem OS, nicht die JVM. Es geht darum, wie Ihr OS Griffe threads.
Könnten Sie teilen Sie Ihre Java-threads in separaten Prozessen und packen Sie Sie in nativen code zu setzen, einen Prozess pro Kern. Dies bedeutet natürlich, erschweren die Kommunikation, inter-Prozess-anstelle von inter-thread. Wie auch immer, dies ist, wie beliebt grid-computing-Anwendungen wie boink Arbeit.
Andernfalls bist du auf die Gnade des OS zu planen, die Fäden.
InformationsquelleAutor der Antwort Marcus Adams
Ich würde diese Vermutung ist die auf der JVM/OS und nicht unbedingt Ihren code. Überprüfen Sie die verschiedenen JVM-performance-tuning-docs von Sun, z.B. http://ch.sun.com/sunnews/events/2009/apr/adworkshop/pdf/5-1-Java-Performance.pdf die schlägt mit
numactl
auf Linux zu setzen, die Affinität.Glück!
InformationsquelleAutor der Antwort ShiDoiSi
Offenbar Ihre VM läuft im sogenannten "client-Modus", wo alle Java-threads zugeordnet sind, die eine native OS-thread, und folglich werden von einer einzigen CPU-Kern. Versuchen Sie zum aufrufen der JVM mit
-server
wechseln, dies sollte das problem beheben.Wenn Sie Holen Sie sich ein:
Error: no 'server' JVM
gefunden haben, müssen Sie kopieren dieserver
- Verzeichnis vom JDK istjre\bin
Verzeichnis JRE istbin
.InformationsquelleAutor der Antwort johnidis
uname-a
2.6.18-194.11.4.el5 #1 SMP Tue Sep 21 05:04:09 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux
Intel(R) Xeon(R) CPU E5530 @ 2.40 GHz
http://browse.geekbench.ca/geekbench2/view/182101
Java 1.6.0_20-b02
16cores, das Programm verbraucht 100% cpu gezeigt hat, ist vmstat
Interessanterweise kam ich auf diese Artikel, weil ich besorge, mein Antrag nicht unter Verwendung aller Kerne, wie die cpu-Auslastung nie erhöht, aber die Reaktionszeit verschlechtert
InformationsquelleAutor der Antwort Nikhil
Habe ich bemerkt, noch auf C, die eine enge Schleife hat oft Themen wie das. Sie sehen auch ziemlich große Unterschiede, je nach OS.
Je nach reporting-tool Sie verwenden, kann es nicht zu berichten, die CPU wird von einigen core services.
Java neigt dazu, ziemlich freundlich. Sie könnten versuchen, die gleiche Sache in linux, aber festlegen der Priorität des Prozesses auf einige negative Zahl und sehen, wie es wirkt.
Einstellung thread-Prioritäten innerhalb der app kann ein wenig helfen, auch wenn Sie in der jvm nicht mit grünen Fäden.
Viele Variablen.
InformationsquelleAutor der Antwort Bill K