68

Does anybody know of a way to lock down individual threads within a Java process to specific CPU cores (on Linux)? I've done this in C, but can't find how to do this in Java. My instincts are that this will require a JNI call, but I was hoping someone here might have some insight or might have done it before.

Thanks!

Dave
  • 1,420
  • 3
  • 17
  • 25
  • 1
    See my answer below to Hassan's comment. Some threads are very I/O intensive, others are CPU intensive. If I'm shielding I/O interrupts to a particular core, I'd like the I/O intensive threads to be on cores on the same socket, and I'd like to shield the CPU-intensive threads from the I/O. – Dave Feb 10 '10 at 16:24
  • 46
    @gimpf: as always with this type of "question questionning": SO is not about the "why", it's about the "how". CPU affinity exists for a reason, there's a reason there are utilities under both Linux and Windows to set a process's CPU affinity. The OP's question is a perfectly valid question that wants no "why" but a "how". – SyntaxT3rr0r Feb 10 '10 at 17:22
  • 6
    @WizardOfOdds: I doubt that the "why" is forbidden on SO, and as Java is usually not the first programming language for concurrency-related performance tweaks, I think a sanity check is valid. – gimpf Feb 10 '10 at 21:24
  • Right now I need the answer to this question in order to implement NUMA optimisations. – Tim Cooper Oct 10 '12 at 00:51
  • I love these "Why you want to do this questions?" If a serious engineer ask something please think about it might be serious answer required. – Martin Kersten Feb 26 '15 at 21:15

5 Answers5

49

You can't do this in pure java. But if you really need it -- you can use JNI to call native code which do the job. This is the place to start with:

http://ovatman.blogspot.com/2010/02/using-java-jni-to-set-thread-affinity.html

http://blog.toadhead.net/index.php/2011/01/22/cputhread-affinity-in-java/

UPD: After some thinking, I've decided to create my own class for this: ThreadAffinity.java It's JNA-based, and very simple -- so, if you want to use it in production, may be you should spent some time making it more stable, but for benchmarking and testing it works well as is.

UPD 2: There is another library for working with thread affinity in java. It uses same method as previously noted, but has another interface

Julien Kronegg
  • 4,968
  • 1
  • 47
  • 60
BegemoT
  • 3,776
  • 1
  • 24
  • 30
  • +1 Works! Awesome! Note the comment I left in the first blog - you need `#define _GNU_SOURCE` above all the includes. – Erick Robertson Nov 07 '11 at 18:22
  • 1
    +1: I have turned this functionality into a library which uses JNI or JNA depending on what is available. It also has a low latency timer and support busy waiting with the PAUSE asm instruction. https://github.com/peter-lawrey/Java-Thread-Affinity – Peter Lawrey Feb 09 '12 at 09:14
  • @PeterLawrey That's great, thanks! (assuming it works which I have yet to verify). There are some issues with your library (mostly documentation and a bug), though; how can I contact you about that? – Raphael Mar 01 '12 at 11:12
  • 2
    Best to log bugs this way https://github.com/peter-lawrey/Java-Thread-Affinity/issues so they don't get forgotten – Peter Lawrey Mar 01 '12 at 11:55
  • This is really the best way to do it, although my way below works too. – Dave Apr 20 '12 at 22:15
  • Both links are not working. This question is still relevant. Can you please updated the links? – Manu Manjunath Sep 20 '13 at 11:54
  • Don't know how to bring the blogs back :) But the idea is pretty simple, you just do appropriate syscalls via JNA/JNI. Details may be found in 3 or 4 links – BegemoT Sep 26 '13 at 05:36
  • @PeterLawrey - I found this ... Thanks again on the other thread: http://stackoverflow.com/questions/13866123/java-relationship-between-threads-and-cpus/13866186?noredirect=1#comment53518747_13866186 – Xofo Sep 30 '15 at 21:59
9

I know it's been a while, but if anyone comes across this thread, here's how I solved this problem. I wrote a script that would do the following:

  1. "jstack -l "
  2. Take the results, find the "nid"'s of the threads I want to manually lock down to cores.
  3. Taskset those threads.
Dave
  • 1,420
  • 3
  • 17
  • 25
  • 2
    Out of interest, I thought taskset only worked on processes not individual threads. What is the syntax for doing it to a thread? – Matt Apr 22 '11 at 16:45
  • Java code isn't machine code being executed by a processor, it is data being scanned and interpreted by another program (the JVM). The JVM may implement threads in a completely arbitrary manner. Even if the JVM spawns additional processes to execute threads there is no guarantee that when a thread gets dropped it will get picked up again by the same process. And even if it does there's no guarantee that future implementations of the JVM will behave the same way. – Terrible Tadpole Dec 10 '21 at 09:18
4

You might want to take a look at https://github.com/peter-lawrey/Java-Thread-Affinity/blob/master/src/test/java/com/higherfrequencytrading/affinity/AffinityLockBindMain.java

Stephan
  • 41,764
  • 65
  • 238
  • 329
Vaibhav Kamble
  • 3,579
  • 5
  • 23
  • 16
0

IMO, this will not be possible unless you use native calls. JVM is supposed to be platform independent, any system calls done to achieve this will not result in a portable code.

questzen
  • 3,260
  • 18
  • 21
  • 7
    I'm not concerned about portability. – Dave Feb 10 '10 at 16:21
  • 5
    @questzen: and what if the system call is made only if the Java program is found to be run on an OS supporting said call? The code would still be portable but simply not set any CPU affinity on other OSes. This is the one thing that always crack me up: people screaming "non portable code" as soon as you do some JNI or some Runtime.exec(). I've got program that do both and that work on Linux, Windows and OS X. – SyntaxT3rr0r Feb 10 '10 at 17:23
  • It's not about whether to use or not use native calls but about whether the platform supports this "out of the box". @questzen is right that the JVM will not abstract access to this because it's not very platform neutral. You might be able to find third party libraries that will do it. – PSpeed Feb 10 '10 at 21:49
0

It's not possible (at least with plain Java).

You can use thread pools to limit the amount of threads (and therefore cores) used for different types of work, but there is no way to specify a core to use.

There is even the (small) possibility that your Java runtime doesn't support native threading for your OS or hardware. In this case, green threads are used and only one core will be used for the whole JVM.

Hardcoded
  • 6,476
  • 2
  • 22
  • 20