Ermöglicht das Binden eines Threads an einen bestimmten Kern. Dies kann die Leistung verbessern (diese Bibliothek funktioniert am besten unter Linux).
OpenHFT Java Thread Affinity-Bibliothek
Arbeitsbeispiele zur Verwendung dieser Bibliothek finden Sie unter affinity/src/test/java.
V3.2.0 – Unterstützung für Textkonfiguration hinzugefügt
V3.1.1 – JNA-Abhängigkeit auf 4.4.0 aktualisiert
V2.0.1 – getThreadId für den Prozess des Threads hinzugefügt.
Java-Thread-Affinity wird versuchen, JNA zu verwenden, um Zugriff auf native Thread-Verarbeitungsfunktionen bereitzustellen. Um diese Bibliothek optimal nutzen zu können, sollte JNA auf Ihrem System installiert sein.
Java-Thread-Affinity hängt derzeit von der JNA-Version 4.4.0 ab, die wiederum von einer GLIBC-Version >= 2.14 abhängt. Wenn es sich bei Ihrem Betriebssystem um ein altes Betriebssystem mit einer Version von GLIBC handelt, die vor 2011 veröffentlicht wurde, kann diese Bibliothek keine nativen Funktionen aufrufen.
Um dieses Problem zu umgehen, forken Sie das Repository und überschreiben Sie das <version>
-Tag für die Artefakte jna
und jna-platform
in der pom
Datei des Projekts.
sudo apt-get install libjna-java
sudo yum installiere jna
Die Bibliothek liest Ihre /proc/cpuinfo
falls Sie eine haben oder bereitstellen, und bestimmt Ihr CPU-Layout. Wenn Sie keinen haben, wird davon ausgegangen, dass sich jede CPU auf einem CPU-Sockel befindet.
Die Bibliothek sucht nach isolierten CPUs, indem sie sich die CPUs ansieht, auf denen Sie standardmäßig nicht ausgeführt werden. Das heißt, wenn Sie 16 CPUs haben, aber 8 davon nicht für die allgemeine Verwendung verfügbar sind (wie durch die Affinität des Prozesses beim Start bestimmt), beginnt die Zuweisung zu diesen CPUs.
Hinweis: Wenn Sie mehr als einen Prozess haben, der diese Bibliothek verwendet, müssen Sie angeben, welche CPUs der Prozess verwenden kann, andernfalls werden beiden Prozessen dieselben CPUs zugewiesen. Um zu steuern, welche CPUs ein Prozess verwenden kann, fügen Sie -Daffinity.reserved={cpu-mask-in-hex} zur Befehlszeile des Prozesses hinzu.
Hinweis: Die CPU 0 ist für das Betriebssystem reserviert und muss irgendwo ausgeführt werden.
https://github.com/peter-lawrey/Java-Thread-Affinity/wiki/Getting-started
https://github.com/peter-lawrey/Java-Thread-Affinity/wiki/How-it-works
http://vanillajava.blogspot.co.uk/2013/07/micro-jitter-busy-waiting-and-binding.html
Java-Thread-Affinity erfordert, dass Sie zunächst einige CPUs isolieren.
Sobald ein CPU-Kern isoliert ist, verwendet der Linux-Scheduler den CPU-Kern nicht mehr zum Ausführen von User-Space-Prozessen. Die isolierten CPUs nehmen nicht am Lastausgleich teil und auf ihnen werden keine Aufgaben ausgeführt, es sei denn, sie werden ausdrücklich zugewiesen.
Um den 1. und 3. CPU-Kern (CPU-Nummern beginnen bei 0) auf Ihrem System zu isolieren, fügen Sie beim Booten Folgendes zur Kernel-Befehlszeile hinzu:
isolcpus=1,3
Eine Sperre für eine CPU können Sie auf folgende Weise erlangen:
In Java 6
AffinityLock al = AffinityLock . acquireLock ();
try {
// do some work locked to a CPU.
} finally {
al . release ();
}
In Java 7 oder 8
try ( AffinityLock al = AffinityLock . acquireLock ()) {
// do some work while locked to a CPU.
}
Sie haben weitere Optionen wie z.B
Sie können einen ganzen Kern reservieren. Wenn Sie Hyper-Threading aktiviert haben, wird eine CPU beansprucht und die Doppel-CPU bleibt ungenutzt.
try ( AffinityLock al = AffinityLock . acquireCore ()) {
// do some work while locked to a CPU.
}
Sie können ein Layout relativ zu einem vorhandenen Schloss wählen.
try ( final AffinityLock al = AffinityLock . acquireLock ()) {
System . out . println ( "Main locked" );
Thread t = new Thread ( new Runnable () {
@ Override
public void run () {
try ( AffinityLock al2 = al . acquireLock ( AffinityStrategies . SAME_SOCKET ,
AffinityStrategies . ANY )) {
System . out . println ( "Thread-0 locked" );
}
}
});
t . start ();
}
In diesem Beispiel bevorzugt die Bibliothek eine freie CPU auf demselben Socket wie der erste Thread, andernfalls wählt sie eine beliebige freie CPU aus.
Sie können die aktuelle Thread-ID mit abrufen
int threadId = AffinitySupport . getThreadId ();
Sie können die aktuelle CPU-Auslastung abrufen
int cpuId = AffinitySupport . getCpu ();
Die Affinität des Prozesses beim Start beträgt
long baseAffinity = AffinityLock . BASE_AFFINITY ;
Die verfügbare CPU für die Reservierung beträgt
long reservedAffinity = AffinityLock . RESERVED_AFFINITY ;
Wenn Sie die Affinität direkt abrufen/festlegen möchten, können Sie dies tun
long currentAffinity = AffinitySupport . getAffinity ();
AffinitySupport . setAffinity ( 1L << 5 ); // lock to CPU 5.
Um eine detaillierte Ansicht des aktuellen Affinitätsstatus (wie von der Bibliothek angezeigt) zu erhalten, führen Sie das folgende Skript auf Linux-Systemen aus:
# change to the affinity lock-file directory (defaults to system property java.io.tmpdir)
$ cd /tmp
# dump affinity state
$ for i in "$(ls cpu-*)";
do PID="$(cat $i | head -n1)"; TIMESTAMP="$(cat $i | tail -n1)";
echo "pid $PID locked at $TIMESTAMP in $i"; taskset -cp $PID;
cat "/proc/$PID/cmdline"; echo; echo
done
pid 14584 locked at 2017.10.30 at 10:33:24 GMT in cpu-3.lock
pid 14584's current affinity list: 3
/opt/jdk1.8.0_141/bin/java ...
Java Thread Affinity-Supportgruppe
Einen Artikel darüber, welchen Unterschied Affinität machen kann und wie man sie nutzt, finden Sie unter http://vanillajava.blogspot.com/2013/07/micro-jitter-busy-waiting-and-binding.html
Ich arbeite derzeit an einem Projekt zur Deadlock-Erkennung in Multithread-Programmen in Java. Wir versuchen, Threads auf verschiedenen Prozessoren auszuführen und sind daher auf Ihre Github-Beiträge zu diesem Thema gestoßen. https://github.com/peter-lawrey/Java-Thread-Affinity/wiki/Getting-started Als Anfänger habe ich wenig Wissen und brauche daher Ihre Hilfe. Wir müssen wissen, wie man Threads auf einer bestimmten CPU-Nummer ausführt und dann Threads wechselt, wenn einer wartet.
// lock a cpuId
try ( AffinityLock lock = AffinityLock . acquireLock ( n )) {
}
Dabei ist n die CPU, auf der Sie den Thread ausführen möchten.
ODER
// lock one of the last CPUs
try ( AffinityLock lock = AffinityLock . acquireLockLastMinus ( n )) {
}
Ich habe die CPU-ID in einer Konfigurationsdatei. Wie kann ich sie mithilfe einer Zeichenfolge festlegen?
try ( AffinityLock lock = AffinityLock . acquireLock ( "last" )) {
assertEquals ( PROCESSORS - 1 , Affinity . getCpu ());
}
try ( AffinityLock lock = AffinityLock . acquireLock ( "last-1" )) {
assertEquals ( PROCESSORS - 2 , Affinity . getCpu ());
}
try ( AffinityLock lock = AffinityLock . acquireLock ( "1" )) {
assertEquals ( 1 , Affinity . getCpu ());
}
try ( AffinityLock lock = AffinityLock . acquireLock ( "any" )) {
assertTrue ( lock . bound );
}
try ( AffinityLock lock = AffinityLock . acquireLock ( "none" )) {
assertFalse ( lock . bound );
}
try ( AffinityLock lock = AffinityLock . acquireLock (( String ) null )) {
assertFalse ( lock . bound );
}
try ( AffinityLock lock = AffinityLock . acquireLock ( "0" )) { // prints a warning
assertFalse ( lock . bound );
}