특정 코어에 스레드를 바인딩하면 성능이 향상될 수 있습니다(이 라이브러리는 Linux에서 가장 잘 작동합니다).
OpenHFT Java 스레드 선호도 라이브러리
이 라이브러리를 사용하는 방법에 대한 작업 예제는affinity/src/test/java를 참조하세요.
V3.2.0 - 텍스트 구성 지원 추가
V3.1.1 - JNA 종속성을 4.4.0으로 업그레이드했습니다.
V2.0.1 - 스레드의 경우 프로세스에 대한 getThreadId가 추가되었습니다.
Java-Thread-Affinity는 JNA를 사용하여 기본 스레드 처리 기능에 대한 액세스를 제공하려고 시도합니다. 이 라이브러리를 최대한 활용하려면 시스템에 JNA를 설치해야 합니다.
Java-Thread-Affinity는 현재 JNA 버전 4.4.0에 의존하며, 이는 차례로 GLIBC >= 2.14 버전에 의존합니다. 운영 체제가 2011년 이전에 릴리스된 GLIBC 버전을 사용하는 오래된 운영 체제인 경우 이 라이브러리는 기본 기능을 호출할 수 없습니다.
이 문제를 해결하려면 저장소를 포크하고 프로젝트의 pom
파일에서 아티팩트 jna
및 jna-platform
에 대한 <version>
태그를 재정의하세요.
sudo apt-get libjna-java 설치
sudo yum 설치 jna
라이브러리는 /proc/cpuinfo
가 있거나 제공하는 경우 이를 읽고 CPU 레이아웃을 결정합니다. CPU가 없으면 모든 CPU가 하나의 CPU 소켓에 있다고 가정합니다.
라이브러리는 기본적으로 실행되지 않는 CPU를 확인하여 격리된 CPU를 찾습니다. 즉, 16개의 CPU가 있지만 그 중 8개를 일반 용도로 사용할 수 없는 경우(시작 시 프로세스의 선호도에 따라 결정됨) 해당 CPU에 할당이 시작됩니다.
참고: 이 라이브러리를 사용하는 프로세스가 두 개 이상인 경우 프로세스가 사용할 수 있는 CPU를 지정해야 합니다. 그렇지 않으면 두 프로세스에 동일한 CPU가 할당됩니다. 프로세스가 사용할 수 있는 CPU를 제어하려면 프로세스의 명령줄에 -Daffinity.reserved={cpu-mask-in-hex}를 추가하세요.
참고: CPU 0은 운영 체제용으로 예약되어 있으므로 어딘가에서 실행되어야 합니다.
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-bound.html
Java-Thread-Affinity를 사용하려면 먼저 일부 CPU를 격리해야 합니다.
CPU 코어가 격리되면 Linux 스케줄러는 CPU 코어를 사용하여 사용자 공간 프로세스를 실행하지 않습니다. 격리된 CPU는 로드 밸런싱에 참여하지 않으며 명시적으로 할당되지 않는 한 CPU에서 작업이 실행되지 않습니다.
시스템에서 첫 번째와 세 번째 CPU 코어(CPU 번호는 0부터 시작)를 분리하려면 부팅하는 동안 커널 명령줄에 다음을 추가하세요.
아이소클퍼스=1,3
다음과 같은 방법으로 CPU에 대한 잠금을 획득할 수 있습니다.
자바 6에서
AffinityLock al = AffinityLock . acquireLock ();
try {
// do some work locked to a CPU.
} finally {
al . release ();
}
자바 7 또는 8에서
try ( AffinityLock al = AffinityLock . acquireLock ()) {
// do some work while locked to a CPU.
}
다음과 같은 추가 옵션이 있습니다.
전체 코어를 예약할 수 있습니다. 하이퍼스레딩을 활성화한 경우 CPU 한 개를 사용하고 트윈 CPU는 사용하지 않은 상태로 둡니다.
try ( AffinityLock al = AffinityLock . acquireCore ()) {
// do some work while locked to a CPU.
}
기존 잠금을 기준으로 레이아웃을 선택할 수 있습니다.
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 ();
}
이 예에서 라이브러리는 첫 번째 스레드와 동일한 소켓에 있는 사용 가능한 CPU를 선호하고, 그렇지 않으면 사용 가능한 CPU를 선택합니다.
다음을 사용하여 현재 스레드 ID를 얻을 수 있습니다.
int threadId = AffinitySupport . getThreadId ();
현재 사용중인 CPU를 확인할 수 있습니다.
int cpuId = AffinitySupport . getCpu ();
시작 시 프로세스의 선호도는 다음과 같습니다.
long baseAffinity = AffinityLock . BASE_AFFINITY ;
예약 가능한 CPU는 다음과 같습니다.
long reservedAffinity = AffinityLock . RESERVED_AFFINITY ;
선호도를 직접 얻거나 설정하려면 다음을 수행하십시오.
long currentAffinity = AffinitySupport . getAffinity ();
AffinitySupport . setAffinity ( 1L << 5 ); // lock to CPU 5.
현재 선호도 상태(라이브러리에 표시된)에 대한 자세한 내용을 보려면 Linux 시스템에서 다음 스크립트를 실행하세요.
# 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 스레드 친화성 지원 그룹
유사성이 얼마나 큰 차이를 만들 수 있는지와 이를 사용하는 방법에 대한 기사는 http://vanillajava.blogspot.com/2013/07/micro-jitter-busy-waiting-and-bound.html입니다.
저는 현재 Java의 다중 스레드 프로그램에서 교착 상태 감지와 관련된 프로젝트를 진행하고 있습니다. 우리는 다른 프로세서에서 스레드를 실행하려고 시도하고 있으며 이에 대한 귀하의 github 게시물을 발견했습니다. https://github.com/peter-lawrey/Java-Thread-Affinity/wiki/Getting-started 초보자이기 때문에 지식이 거의 없으므로 도움이 필요합니다. 지정된 CPU 번호에서 스레드를 실행한 다음 대기 중인 스레드를 전환하는 방법을 알아야 합니다.
// lock a cpuId
try ( AffinityLock lock = AffinityLock . acquireLock ( n )) {
}
여기서 n은 스레드를 실행하려는 CPU입니다.
또는
// lock one of the last CPUs
try ( AffinityLock lock = AffinityLock . acquireLockLastMinus ( n )) {
}
구성 파일에 cpuId가 있는데 문자열을 사용하여 어떻게 설정할 수 있나요?
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 );
}