2013-03-11 5 views
8

Ich möchte eine CoreLocal Map implementieren, die genau wie ThreadLocal funktioniert, 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 den Vorzug geben, deren zugehörige Daten sich bereits im selben L1-Cache befinden wie der Thread, der den Thread auswählt Job aus der Warteschlange. Statt einer Jobwarteschlange für das gesamte Programm möchte ich also eine Warteschlange für jeden Kern haben, und nur wenn eine Warteschlange leer ist, wird ein Worker-Thread die Warteschlangen anderer Kerne ansehen.Wie kann ich feststellen, auf welchem ​​Kern ein Java-Thread läuft?

+3

https://github.com/peter-lawrey/Java-Thread-Affinity – bmargulies

+2

Q == Warteschlange? : \ –

+3

Hört sich an, als ob Sie dort im Nanosekundenbereich sehr tief sind. – djechlin

Antwort

0

wahrscheinlich könnten Sie /proc/[pid]/status

Diese Felder überprüfen hilfreich sein können:

Cpus_allowed: Die Maske des CPUs, auf denen dieser Prozess

Cpus_allowed_list laufen kann: Das gleiche wie zuvor, jedoch in „-Liste format "

1

Es gibt eine verwandte linux question ohne zufriedenstellende Antwort (Parsing top Ausgabe zählt nicht und die angenommene Antwort funktioniert nicht mehr). Ich dachte, dass

/proc/<pid>/task/<tid>/sched 

diese Informationen in einer Zeile geben könnte wie

current_node=0, numa_group_id=0 

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

Ich konnte keine Dokumentation finden, oder verpasst es in this document.


Aber ich habe Angst, dass dies diese Informationen zu erhalten unwahrscheinliche Ihnen helfen könnten:

  • aus dem proc-Dateisystem Lesen auf der Skala teuer sein, kann Sie gerade arbeiten.
  • Im Gegensatz zu ThreadLocal ist Ihre CoreLocal nicht Thread-sicher: Migrieren eines Threads zu einem anderen Kern könnte sogar triviale nicht-atomare Operationen wie someCoreLocalField++ verderben. Aussetzen würde es auch tun. Man braucht also Atomics oder Thread-Locals, um es zum Laufen zu bringen, was es wiederum viel zu langsam für das macht, was man will.
0

Ich glaube nicht, dass jeder Anruf ist die aktuelle CPU-Zeit in dem JDK ausgesetzt zu bekommen, obwohl es sicherlich previously discussed und proposed as a JDK enhancement war.

Ich denke, bis so etwas umgesetzt wird Ihre beste Wette so etwas wie JNA (am einfachsten) oder JNI (schnell) wickeln einen native Systemaufruf wie getcpu unter Linux oder GetCurrentProcessorNumber unter Windows zu verwenden ist.

Zumindest unter Linux ist getcpu im 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 brauchen Geschwindigkeit, könnten Sie immer die Funktion als eine intrinsische zu einer maßgeschneiderten JVM hinzufügen (da OpenJDK Open Source ist). Das würde einige Nanosekunden abschneiden.

Denken Sie daran, dass diese Informationen veraltet sein können, sobald Sie sie erhalten, also sollten Sie sich nie auf die Leistung verlassen, nur die Korrektheit. Da Sie bereits Unterstützung beim Abrufen des "falschen" Werts haben, besteht ein weiterer möglicher Ansatz darin, den zwischengespeicherten Wert der CPU-ID in einem ThreadLocal zu speichern und nur periodisch zu aktualisieren. Dies macht langsam Ansätze wie das Analysieren der /proc Dateisystem lebensfähig, da Sie sie nur selten tun. Für maximale Geschwindigkeit 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.


Sowohl die Diskussion und die Verbesserung Anfrage sind Lese sehr zu empfehlen.

Verwandte Themen