Memungkinkan Anda mengikat thread ke inti tertentu, ini dapat meningkatkan kinerja (perpustakaan ini berfungsi paling baik di linux).
Pustaka Afinitas Utas Java OpenHFT
Lihat affinity/src/test/java untuk contoh kerja cara menggunakan perpustakaan ini.
V3.2.0 - Tambahkan dukungan untuk konfigurasi teks
V3.1.1 - Peningkatan ketergantungan JNA ke 4.4.0
V2.0.1 - Menambahkan getThreadId untuk proses thread.
Java-Thread-Affinity akan mencoba menggunakan JNA untuk menyediakan akses ke fungsi penanganan thread asli. JNA harus diinstal pada sistem Anda untuk mendapatkan hasil maksimal dari perpustakaan ini.
Java-Thread-Affinity saat ini bergantung pada JNA versi 4.4.0, yang selanjutnya bergantung pada versi GLIBC >= 2.14. Jika sistem operasi Anda sudah lama, dengan versi GLIBC yang dirilis sebelum 2011, perpustakaan ini tidak akan dapat menjalankan fungsi asli.
Untuk mengatasi masalah ini, fork repositori, dan ganti tag <version>
untuk artefak jna
dan jna-platform
dalam file pom
proyek.
sudo apt-get install libjna-java
sudo yum instal jna
Pustaka akan membaca /proc/cpuinfo
Anda jika Anda memilikinya atau menyediakannya dan itu akan menentukan tata letak CPU Anda. Jika Anda tidak memilikinya, maka setiap CPU akan berada pada satu soket CPU.
Pustaka mencari CPU terisolasi yang ditentukan dengan melihat CPU yang tidak Anda jalankan secara default. yaitu jika Anda memiliki 16 CPU tetapi 8 di antaranya tidak tersedia untuk penggunaan umum (sebagaimana ditentukan oleh afinitas proses saat startup) maka CPU tersebut akan mulai ditugaskan ke CPU tersebut.
Catatan: jika Anda memiliki lebih dari satu proses yang menggunakan perpustakaan ini, Anda perlu menentukan CPU mana yang dapat digunakan oleh proses tersebut, jika tidak maka proses tersebut akan menetapkan CPU yang sama untuk kedua proses. Untuk mengontrol CPU mana yang dapat digunakan suatu proses, tambahkan -Daffinity.reserved={cpu-mask-in-hex} ke baris perintah proses.
Catatan: CPU 0 dicadangkan untuk Sistem Operasi, ia harus dijalankan di suatu tempat.
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-binding.html
Java-Thread-Affinity mengharuskan Anda mengisolasi beberapa CPU terlebih dahulu.
Setelah inti CPU diisolasi, penjadwal Linux tidak akan menggunakan inti CPU untuk menjalankan proses ruang pengguna apa pun. CPU yang terisolasi tidak akan berpartisipasi dalam penyeimbangan beban, dan tidak akan menjalankan tugas kecuali ditetapkan secara eksplisit.
Untuk mengisolasi inti CPU ke-1 dan ke-3 (nomor CPU dimulai dari 0) pada sistem Anda, tambahkan perintah berikut ke baris perintah kernel saat boot:
isolcpus=1,3
Anda dapat memperoleh kunci untuk CPU dengan cara berikut:
Di Jawa 6
AffinityLock al = AffinityLock . acquireLock ();
try {
// do some work locked to a CPU.
} finally {
al . release ();
}
Di Jawa 7 atau 8
try ( AffinityLock al = AffinityLock . acquireLock ()) {
// do some work while locked to a CPU.
}
Anda memiliki opsi lebih lanjut seperti
Anda dapat memesan seluruh inti. Jika Anda mengaktifkan hyper-threading, ini akan menggunakan satu CPU dan membiarkan CPU kembarnya tidak digunakan.
try ( AffinityLock al = AffinityLock . acquireCore ()) {
// do some work while locked to a CPU.
}
Anda dapat memilih tata letak yang berhubungan dengan kunci yang ada.
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 ();
}
Dalam contoh ini, perpustakaan akan memilih CPU gratis pada Socket yang sama dengan thread pertama, jika tidak maka perpustakaan akan memilih CPU gratis mana pun.
Anda bisa mendapatkan id thread saat ini menggunakan
int threadId = AffinitySupport . getThreadId ();
Anda bisa mendapatkan CPU yang sedang digunakan
int cpuId = AffinitySupport . getCpu ();
Afinitas proses pada start up adalah
long baseAffinity = AffinityLock . BASE_AFFINITY ;
CPU yang tersedia untuk reservasi adalah
long reservedAffinity = AffinityLock . RESERVED_AFFINITY ;
Jika Anda ingin mendapatkan/mengatur afinitas secara langsung, Anda dapat melakukannya
long currentAffinity = AffinitySupport . getAffinity ();
AffinitySupport . setAffinity ( 1L << 5 ); // lock to CPU 5.
Untuk tampilan detail status afinitas saat ini (seperti yang terlihat di perpustakaan), jalankan skrip berikut di sistem 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 ...
Grup dukungan Java Thread Affinity
Untuk artikel tentang seberapa besar perbedaan yang dapat dihasilkan afinitas dan cara menggunakannya http://vanillajava.blogspot.com/2013/07/micro-jitter-busy-waiting-and-binding.html
Saat ini saya sedang mengerjakan proyek yang berkaitan dengan deteksi kebuntuan pada program multithread di java. Kami mencoba menjalankan thread pada prosesor yang berbeda dan menemukan postingan github Anda mengenai hal yang sama. https://github.com/peter-lawrey/Java-Thread-Affinity/wiki/Getting-started Sebagai seorang pemula, saya memiliki sedikit pengetahuan sehingga membutuhkan bantuan Anda. Kita perlu mengetahui cara menjalankan thread pada nomor CPU tertentu dan kemudian mengganti thread ketika ada yang menunggu.
// lock a cpuId
try ( AffinityLock lock = AffinityLock . acquireLock ( n )) {
}
di mana n adalah CPU tempat Anda ingin menjalankan thread.
ATAU
// lock one of the last CPUs
try ( AffinityLock lock = AffinityLock . acquireLockLastMinus ( n )) {
}
Saya memiliki cpuId di file konfigurasi, bagaimana cara mengaturnya menggunakan string?
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 );
}