In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)05/31 Report--
This article mainly introduces "how java binds CPU threads". In daily operation, I believe many people have doubts about how java binds CPU threads. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful to answer the questions of "how java binds CPU threads". Next, please follow the editor to study!
Brief introduction
In modern computer systems, there can be multiple CPU, and each CPU can have multiple cores. In order to make full use of the function of modern CPU, multithreading is introduced into JAVA, and different threads can run in different CPU or different CPU cores at the same time. But for JAVA programmers, you can control how many threads you create, but which CPU the thread is running on is a black box, which is generally difficult to know.
However, if different CPU checks the same thread for scheduling, the performance loss caused by CPU switching may occur. In general, this loss is relatively small, but if your program is particularly concerned about the wear and tear caused by this CPU switch, then you can try today's Java Thread Affinity.
Introduction to Java Thread Affinity
Java thread Affinity is used to bind threads in JAVA code to CPU-specific cores to improve the performance of programs.
Obviously, in order to interact with the underlying CPU, java thread Affinity must use JAVA and native methods to interact. Although JNI is the official JAVA and native method of JAVA to interact, JNI is cumbersome to use. So what java thread Affinity actually uses is JNA,JNA, which is an improved library based on JNI that interacts with native methods.
Let's start by introducing several concepts in CPU, namely CPU,CPU socket and CPU core.
First of all, the full name of CPU,CPU is central processing unit, also known as CPU, which is the key core of task processing.
So what is CPU socket? The so-called socket is to insert the slot of the CPU, if the students who have assembled the desktop computer should know that the CPU is installed on the Socket.
CPU Core refers to the number of cores in CPU. Long ago, CPU was single-core, but with the development of multi-core technology, a CPU can contain multiple cores, and the core in CPU is the real unit for business processing.
If you are on a linux machine, you can check the CPU of the system by using the lscpu command, as shown below:
Architecture: x86_64CPU op-mode (s): 32-bit 64-bitByte Order: Little EndianCPU (s): 1On-line CPU (s) list: 0Thread (s) per core: 1Core (s) per socket: 1Socket (s): 1NUMA node (s): 1Vendor ID: GenuineIntelCPU family: 6Model: 94Model name: Intel (R) Xeon (R) Gold 6148 CPU @ 2.40GHzStepping: 3CPU MHz: 2400.000BogoMIPS: 4800.00Hypervisor vendor: KVMVirtualization type: fullL1d cache: 32KL1i cache: 32KL2 cache: 4096KL3 cache: 28160KNUMA node0 CPU (s): 0Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat Pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single fsgsbase bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx avx512f avx512dq rdseed adx smap avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 arat
From the output above, we can see that this server has a socket, each socket has a core, and each core can process 1 thread at the same time.
This CPU information can be called CPU layout. In linux, the layout information of CPU is stored in / proc/cpuinfo.
There is a CpuLayout interface in Java Thread Affinity to correspond to this information:
Public interface CpuLayout {int cpus (); int sockets (); int coresPerSocket (); int threadsPerCore (); int socketId (int cpuId); int coreId (int cpuId); int threadId (int cpuId);}
According to CPU layout, AffinityStrategies provides some basic Affinity strategies to arrange the distribution relationships between different thread, mainly as follows:
SAME_CORE-runs in the same core. SAME_SOCKET-runs in the same socket, but not on the same core. DIFFERENT_SOCKET-run in different socket DIFFERENT_CORE-run on different core ANY-in any case
These strategies are also distinguished according to CpuLayout's socketId and coreId. Let's take SAME_CORE as an example and click its specific implementation:
SAME_CORE {@ Override public boolean matches (int cpuId, int cpuId2) {CpuLayout cpuLayout = AffinityLock.cpuLayout (); return cpuLayout.socketId (cpuId) = = cpuLayout.socketId (cpuId2) & & cpuLayout.coreId (cpuId) = = cpuLayout.coreId (cpuId2);}}
Affinity policies can be ordered, the previous policy will match first, if not, the second policy will be selected, and so on.
The use of AffinityLock
Next, let's take a look at the specific use of Affinity. The first step is to get a lock of CPU. Before JAVA7, we can write:
AffinityLock al = AffinityLock.acquireLock (); try {/ / do some work locked to a CPU.} finally {al.release ();}
After JAVA7, you can write:
Try (AffinityLock al = AffinityLock.acquireLock ()) {/ / do some work while locked to a CPU.}
The acquireLock method can get any available cpu for the thread. This is a coarse-grained lock. If you want to get fine-grained core, you can use acquireCore:
Try (AffinityLock al = AffinityLock.acquireCore ()) {/ / do some work while locked to a CPU.}
AcquireLock also has a bind parameter that indicates whether to bind the current thread to the obtained cpu lock. If the bind parameter = true, then the current thread will run on the CPU obtained in acquireLock. If the bind parameter = false, it means that acquireLock will bind at some point in the future.
We mentioned AffinityStrategy above, and this AffinityStrategy can be used as a parameter to acquireLock:
Public AffinityLock acquireLock (AffinityStrategy... Strategies) {return acquireLock (false, cpuId, strategies);}
By calling the acquireLock method of the current AffinityLock, you can assign the AffinityLock associated with the previous lock policy to the current thread.
AffinityLock also provides a dumpLocks method to view the current binding status of CPU and thread. Let's give an example:
Private static final ExecutorService ES = Executors.newFixedThreadPool (4, new AffinityThreadFactory ("bg", SAME_CORE, DIFFERENT_SOCKET, ANY); for (int I = 0; I < 12; iTunes +) ES.submit (new Callable () {@ Override public Void call () throws InterruptedException {Thread.sleep (100); return null }}); Thread.sleep; System.out.println ("\ nThe assignment of CPUs is\ n" + AffinityLock.dumpLocks ()); ES.shutdown (); ES.awaitTermination (1, TimeUnit.SECONDS)
In the above code, we created a thread pool of four threads, the corresponding ThreadFactory is AffinityThreadFactory, named the thread pool bg, and assigned three AffinityStrategy. It means first assigning to the same core, then to different socket, and finally to any available CPU.
Then, during the specific execution, we submitted 12 threads, but our Thread pool has only 4 threads at most. It can be predicted that only 4 threads will bind CPU in the result returned by the AffinityLock.dumpLocks method. Let's take a look:
The assignment of CPUs is0: CPU not available1: Reserved for this application2: Reserved for this application3: Reserved for this application4: Thread [BG-4 bg,5,main 5 main] alive=true5: Thread [BG-3 5 bg,5,main] alive=true6: Thread [BG-2 5 bg,5,main] main] alive=true7: Thread [bg,5,main] alive=true
As you can see from the output, CPU0 is not available. The other seven CPU are available, but only four threads are bound, which matches our previous analysis.
Next, let's modify the AffinityStrategy of AffinityThreadFactory as follows:
New AffinityThreadFactory ("bg", SAME_CORE)
Indicates that a thread will only be bound to the same core, because in the current hardware, a core can only support binding of one thread at a time, so you can foresee that only one thread will be bound in the final result. The running result is as follows:
The assignment of CPUs is
0: CPU not available
1: Reserved for this application
2: Reserved for this application
3: Reserved for this application
4: Reserved for this application
5: Reserved for this application
6: Reserved for this application
7: Thread [bg,5,main] alive=true
You can see that only the first thread is bound to CPU, which matches the previous analysis.
Use API to directly assign CPU
The acquireLock method of AffinityLock mentioned above can also accept a CPU id parameter, which can be used directly to get the lock passed into CPU id. This allows subsequent threads to run on the specified CPU.
Public static AffinityLock acquireLock (int cpuId) {return acquireLock (true, cpuId, AffinityStrategies.ANY);}
In real time, this kind of Affinity is stored in BitSet. The index of BitSet is the id of cpu, and the corresponding value is whether to acquire the lock.
Let's take a look at the definition of the setAffinity method:
Public static void setAffinity (int cpu) {BitSet affinity = new BitSet (Runtime.getRuntime (). AvailableProcessors ()); affinity.set (cpu); setAffinity (affinity);}
Take a look at the use of setAffinity:
Long currentAffinity = AffinitySupport.getAffinity (); Affinity.setAffinity (1L
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.