Wie kann ich feststellen, auf welchem ​​Kern ein Java-Thread läuft?

8

Ich möchte eine CoreLocal-Map implementieren, die genauso funktioniert wie ThreadLocal, nur gibt sie einen Wert zurück, der spezifisch für den Kern ist, auf dem der aktuelle Thread läuft.

Der Grund dafür ist, dass ich Code schreiben möchte, der einen Job aus einer Warteschlange nimmt, aber ich möchte Jobs Priorität geben, deren zugehörige Daten sich bereits im selben L1-Cache befinden wie der Thread, der den Job auswählt aus der Warteschlange. Daher möchte ich statt einer Jobwarteschlange für das gesamte Programm eine Warteschlange für jeden Kern haben und nur wenn eine Warteschlange leer ist, wird ein Worker-Thread die Warteschlangen anderer Kerne ansehen.

    
gregw 11.03.2013, 22:49
quelle

3 Antworten

1

Es gibt eine verwandte Linux-Frage ohne zufriedenstellende Antwort (parsing top output zählt nicht und die akzeptierte Antwort funktioniert nicht mehr). Ich dachte das

%Vor%

könnte diese Information in einer Zeile wie

angeben %Vor%

aber auf meinem i5-2400, der einen 4.4.0-92-generischen Kernel ausführt, ist diese Zeile immer die gleiche für alle Threads. Ich denke, "Knoten" bedeutet eine ganze CPU (Socket) und ich habe nur eine.

Ich konnte keine Dokumentation dazu finden oder verpasste es in diesem Dokument .

Ich befürchte jedoch, dass Ihnen das Erhalten dieser Informationen wahrscheinlich helfen könnte:

  • Das Lesen aus dem proc-Dateisystem kann in dem Umfang, an dem Sie gerade arbeiten, zu kostspielig sein.
  • Im Gegensatz zu ThreadLocal ist Ihr CoreLocal nicht threadsicher: Wenn ein Thread in einen anderen Kern migriert wird, können selbst triviale nicht-atomare Operationen wie someCoreLocalField++ beschädigt werden. Aussetzen würde es auch tun. Du brauchst also Atomics oder Thread-Locals, um es zum Laufen zu bringen, was es wiederum viel zu langsam für das macht, was du willst.
maaartinus 11.09.2017 20:14
quelle
0

Wahrscheinlich könntest du /proc/[pid]/status

überprüfen

Diese Felder können hilfreich sein:

  

Cpus_allowed: Maske der CPUs, auf denen dieser Prozess laufen darf

     

Cpus_allowed_list: Wie zuvor, aber im "Listenformat"

    
zzk 11.03.2013 23:04
quelle
0

Ich glaube nicht, dass es einen Aufruf gibt, um die aktuelle CPU aktuell im JDK verfügbar zu machen, obwohl es sicherlich zuvor diskutiert 1 und vorgeschlagen als JDK-Erweiterung .

Ich denke, bis so etwas umgesetzt wird, ist es am besten, etwas wie JNA (am einfachsten) zu verwenden JNI (schnell), um einen systemeigenen Systemaufruf wie getcpu unter Linux oder GetCurrentProcessorNumber unter Windows.

Wenigstens unter Linux ist getcpu in der VDSO ohne Kernel-Übergang implementiert, also sollte es nur ein paar Nanosekunden plus ein paar Nanosekunden mehr für den JNI-Aufruf dauern. JNA ist langsamer.

Wenn Sie wirklich Geschwindigkeit benötigen, können Sie die Funktion immer zu einer maßgeschneiderten JVM hinzufügen (da OpenJDK Open Source ist). Das würde einige Nanosekunden abschneiden.

Beachten Sie, dass diese Informationen veraltet sein können, sobald Sie sie erhalten, also sollten Sie sich niemals auf die Leistung verlassen, nur auf die Korrektheit. Da Sie bereits Unterstützung beim Abrufen des "falschen" Werts erhalten haben, besteht ein weiterer möglicher Ansatz darin, den zwischengespeicherten Wert der CPU-ID in ThreadLocal zu speichern und nur periodisch zu aktualisieren. Dies macht Slow-Ansätze wie das Parsen des /proc -Dateisystems möglich, da sie nur selten ausgeführt werden. Um die maximale Geschwindigkeit zu erreichen, können Sie den Thread-Local in regelmäßigen Abständen von einem Timer-Thread ungültig machen, anstatt die Ungültigkeitsbedingung bei jedem Aufruf zu überprüfen.

1 Sowohl die Diskussion als auch die Verbesserungsanfrage werden dringend empfohlen.

    
BeeOnRope 12.09.2017 02:56
quelle