Kami ingin meningkatkan OS di server kami dari Ubuntu 10.04 LTS ke Ubuntu 12.04 LTS. Sayangnya, tampaknya latensi untuk menjalankan thread yang dapat dijalankan telah meningkat secara signifikan dari kernel 2.6 ke kernel 3.2. Faktanya, angka latensi yang kami dapatkan sulit dipercaya.
Izinkan saya lebih spesifik tentang tes ini. Kami memiliki program yang menjalankan dua utas. Utas pertama mendapatkan waktu saat ini (dalam tanda centang menggunakan RDTSC) dan kemudian memberi sinyal variabel kondisi sekali dalam satu detik. Utas kedua menunggu pada variabel kondisi dan bangun ketika diberi sinyal. Ini kemudian mendapatkan waktu saat ini (di kutu menggunakan RDTSC). Perbedaan antara waktu di utas kedua dan waktu di utas pertama dihitung dan ditampilkan di konsol. Setelah ini, thread kedua menunggu variabel kondisi sekali lagi. Ini akan ditandai lagi oleh utas pertama setelah sekitar satu lintasan kedua.
Jadi, singkatnya kita mendapatkan komunikasi thread ke thread melalui pengukuran latensi variabel kondisi sekali dalam satu detik sebagai hasilnya.
Di kernel 2.6.32, latensi ini berada di urutan 2.8-3.5 us, yang masuk akal. Di kernel 3.2.0, latensi ini telah meningkat ke suatu tempat di urutan 40-100 kami. Saya telah mengecualikan perbedaan perangkat keras antara kedua host. Mereka berjalan pada perangkat keras yang sama (prosesor soket ganda X5687 {Westmere-EP} yang berjalan pada 3,6 GHz dengan hyperthreading, speedstep dan semua status C dimatikan). Aplikasi pengujian mengubah afinitas utas untuk menjalankannya pada inti fisik independen dari soket yang sama (mis., Utas pertama dijalankan pada Inti 0 dan utas kedua dijalankan pada Inti 1), jadi tidak ada utas yang terpental pada core atau memantul / komunikasi antar soket.
Satu-satunya perbedaan antara kedua host adalah yang satu menjalankan Ubuntu 10.04 LTS dengan kernel 2.6.32-28 (kotak sakelar konteks cepat) dan yang lainnya menjalankan Ubuntu 12.04 LTS terbaru dengan kernel 3.2.0-23 (konteks lambat kotak saklar). Semua pengaturan BIOS dan perangkat keras identik.
Apakah ada perubahan dalam kernel yang dapat menyebabkan kelambatan konyol ini dalam berapa lama waktu yang dibutuhkan untuk sebuah utas dijadwalkan untuk berjalan?
Pembaruan: Jika Anda ingin menjalankan pengujian pada host dan linux build Anda, saya telah memposting kode ke pastebin untuk dibaca dengan teliti. Kompilasi dengan:
g++ -O3 -o test_latency test_latency.cpp -lpthread
Jalankan dengan (dengan asumsi Anda memiliki setidaknya kotak dual-core):
./test_latency 0 1 # Thread 1 on Core 0 and Thread 2 on Core 1
Pembaruan 2 : Setelah banyak mencari melalui parameter kernel, posting tentang perubahan kernel dan penelitian pribadi, saya telah menemukan apa masalahnya dan telah memposting solusi sebagai jawaban untuk pertanyaan ini.
sumber
/proc/sys/kernel/*
mungkin berhasil? Jika Anda menemukan sesuatu yang berfungsi, masukkan konfigurasi itu/etc/sysctl.conf
atau file/etc/sysctl.d/
untuk membuatnya tetap ada saat reboot.Jawaban:
Solusi untuk masalah kinerja thread wake up yang buruk di kernel baru-baru ini berkaitan dengan peralihan ke
intel_idle
driver cpuidle dariacpi_idle
, driver yang digunakan di kernel lama. Sayangnya,intel_idle
pengemudi mengabaikan konfigurasi BIOS pengguna untuk status-C dan menari mengikuti iramanya sendiri . Dengan kata lain, bahkan jika Anda benar-benar menonaktifkan semua status C di BIOS PC (atau server) Anda, driver ini akan tetap memaksanya selama periode tidak aktif yang singkat, yang hampir selalu terjadi kecuali jika semua inti memakan benchmark sintetis (mis., Stres ) sedang berlari. Anda dapat memantau transisi status C, bersama dengan informasi berguna lainnya yang terkait dengan frekuensi prosesor, menggunakan alat Google i7z yang luar biasa di sebagian besar perangkat keras yang kompatibel.Untuk melihat driver cpuidle mana yang saat ini aktif di pengaturan Anda, cukup catkan
current_driver
file dicpuidle
bagian/sys/devices/system/cpu
sebagai berikut:Jika Anda ingin OS Linux modern Anda memiliki latensi sakelar konteks serendah mungkin, tambahkan parameter boot kernel berikut untuk menonaktifkan semua fitur hemat daya ini:
Di Ubuntu 12.04, Anda dapat melakukan ini dengan menambahkannya ke
GRUB_CMDLINE_LINUX_DEFAULT
entri/etc/default/grub
dan kemudian menjalankannyaupdate-grub
. Parameter boot yang akan ditambahkan adalah:Berikut adalah detail berdarah tentang apa yang dilakukan ketiga opsi boot:
Mengatur
intel_idle.max_cstate
ke nol akan mengembalikan driver cpuidle Anda keacpi_idle
(setidaknya sesuai dengan dokumentasi opsi), atau menonaktifkannya sepenuhnya. Di kotak saya itu benar-benar dinonaktifkan (yaitu, menampilkancurrent_driver
file dalam/sys/devices/system/cpu/cpuidle
menghasilkan outputnone
). Dalam hal ini, opsi boot keduaprocessor.max_cstate=0
tidak diperlukan. Namun, dokumentasi menyatakan bahwa pengaturan max_cstate ke nol untukintel_idle
driver harus mengembalikan OS keacpi_idle
driver. Oleh karena itu, saya memasukkan opsi boot kedua untuk berjaga-jaga.The
processor.max_cstate
pilihan menetapkan negara maksimum C untukacpi_idle
pengemudi ke nol, mudah-mudahan nonaktifkan juga. Saya tidak memiliki sistem untuk menguji ini, karenaintel_idle.max_cstate=0
benar-benar menghentikan driver cpuidle pada semua perangkat keras yang tersedia untuk saya. Namun, jika instalasi Anda mengembalikan Anda dariintel_idle
keacpi_idle
hanya dengan opsi boot pertama, beri tahu saya jika opsi kedua,processor.max_cstate
melakukan apa yang didokumentasikan untuk dilakukan di komentar sehingga saya dapat memperbarui jawaban ini.Terakhir, yang terakhir dari tiga parameter,
idle=poll
adalah babi kekuatan nyata. Ini akan menonaktifkan C1 / C1E, yang akan menghapus sisa latensi terakhir dengan mengorbankan lebih banyak konsumsi daya, jadi gunakan yang itu hanya jika benar-benar diperlukan. Untuk sebagian besar hal ini akan berlebihan, karena latensi C1 * tidak terlalu besar. Menggunakan aplikasi pengujian saya yang berjalan pada perangkat keras yang saya jelaskan dalam pertanyaan asli, latensi berubah dari 9 kita menjadi 3 kita. Ini tentu saja merupakan pengurangan yang signifikan untuk aplikasi yang sangat sensitif latensi (misalnya, perdagangan keuangan, telemetri / pelacakan presisi tinggi, akuisisi data frekuensi tinggi, dll ...), tetapi mungkin tidak sepadan dengan daya listrik yang dikeluarkan untuk sebagian besar aplikasi desktop. Satu-satunya cara untuk mengetahui secara pasti adalah dengan membuat profil peningkatan kinerja aplikasi Anda vs.Memperbarui:
Setelah pengujian tambahan dengan berbagai
idle=*
parameter, saya menemukan bahwa pengaturanidle
kemwait
jika didukung oleh perangkat keras Anda adalah ide yang jauh lebih baik. Tampaknya penggunaanMWAIT/MONITOR
instruksi memungkinkan CPU untuk memasuki C1E tanpa adanya latensi yang terlihat ditambahkan ke waktu bangun thread. Denganidle=mwait
, Anda akan mendapatkan suhu CPU yang lebih dingin (dibandingkan denganidle=poll
), penggunaan daya yang lebih sedikit, dan masih mempertahankan latensi rendah yang sangat baik dari loop idle polling. Oleh karena itu, rangkaian parameter boot yang saya rekomendasikan untuk latensi bangun thread CPU rendah berdasarkan temuan ini adalah:Penggunaan
idle=mwait
alih - alihidle=poll
juga dapat membantu inisiasi Turbo Boost (dengan membantu CPU tetap di bawah TDP [Daya Desain Termal]) dan hyperthreading (yang MWAIT adalah mekanisme ideal untuk tidak mengonsumsi seluruh inti fisik sementara pada saat yang sama waktu menghindari status C yang lebih tinggi). Ini belum terbukti dalam pengujian, bagaimanapun, yang akan terus saya lakukan.Perbarui 2:
The
mwait
pilihan menganggur telah dihapus dari kernel 3.x yang lebih baru (terima kasih kepada pengguna ck_ untuk update). Itu membuat kita memiliki dua pilihan:idle=halt
- Seharusnya bekerja sebaik itumwait
, tetapi uji untuk memastikan bahwa ini masalahnya dengan perangkat keras Anda. TheHLT
instruksi hampir setara denganMWAIT
dengan negara petunjuk 0. Masalah terletak pada kenyataan bahwa interupsi diperlukan untuk keluar dari keadaan HLT, sementara write memori (atau interrupt) dapat digunakan untuk keluar dari negara MWAIT. Bergantung pada apa yang Kernel Linux gunakan dalam loop diamnya, ini dapat membuat MWAIT berpotensi lebih efisien. Jadi, seperti yang saya katakan, uji / profil dan lihat apakah itu memenuhi kebutuhan latensi Anda ...dan
idle=poll
- Opsi kinerja tertinggi, dengan mengorbankan daya dan panas.sumber
Mungkin yang menjadi lebih lambat adalah futex, blok penyusun untuk variabel kondisi. Ini akan menjelaskan:
kemudian
yang akan menampilkan mikrodetik yang diambil untuk panggilan sistem yang menarik, diurutkan berdasarkan waktu.
Pada kernel 2.6.32
Pada kernel 3.1.9
Saya menemukan laporan bug berusia 5 tahun ini yang berisi tes kinerja "ping pong" yang sebanding
Saya harus menambahkan
untuk mengkompilasi, yang saya lakukan dengan perintah ini
Pada kernel 2.6.32
Pada kernel 3.1.9
Saya menyimpulkan bahwa antara kernel 2.6.32 dan 3.1.9 saklar konteks memang melambat, meskipun tidak sebanyak yang Anda amati di kernel 3.2. Saya menyadari ini belum menjawab pertanyaan Anda, saya akan terus menggali.
Sunting: Saya telah menemukan bahwa mengubah prioritas waktu nyata dari proses (kedua utas) meningkatkan kinerja pada 3.1.9 agar sesuai dengan 2.6.32. Namun, menyetel prioritas yang sama pada 2.6.32 membuatnya melambat ... lihat saja - Saya akan memeriksanya lebih lanjut.
Inilah hasil saya sekarang:
Pada kernel 2.6.32
Pada kernel 3.1.9
sumber
Anda mungkin juga melihat prosesor mengklik ke bawah dalam proses yang lebih baru dan kernel Linux karena driver pstate yang terpisah dari c-state. Jadi sebagai tambahan, untuk menonaktifkan ini, Anda menggunakan parameter kernel berikut:
intel_pstate=disable
sumber