Melihat sumber strace
saya menemukan penggunaan bendera klon CLONE_IDLETASK
yang dijelaskan di sana sebagai:
#define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
Setelah melihat lebih dalam ke dalamnya saya menemukan bahwa, meskipun flag itu tidak tercakup di man clone
dalamnya sebenarnya digunakan oleh kernel selama proses boot untuk membuat proses idle (semuanya harus memiliki PID 0) untuk setiap CPU pada mesin. yaitu mesin dengan 8 CPU akan memiliki setidaknya 7 (lihat pertanyaan di bawah) proses seperti "berjalan" (catatan kutipan).
Sekarang, ini membawa saya pada beberapa pertanyaan tentang apa sebenarnya proses "idle" itu lakukan. Asumsi saya adalah bahwa ia mengeksekusi operasi NOP terus menerus sampai jangka waktunya berakhir dan kernel memberikan proses nyata untuk menjalankan atau menetapkan proses idle sekali lagi (jika CPU tidak sedang digunakan). Namun, itu dugaan lengkap. Begitu:
Pada mesin dengan, katakanlah, 8 CPU akankah 7 proses diam tersebut dibuat? (dan satu CPU akan dipegang oleh kernel itu sendiri sementara tidak ada pekerjaan userspace melakukan?)
Apakah proses idle benar-benar hanya aliran operasi NOP yang tak terbatas? (atau loop yang melakukan hal yang sama).
Apakah penggunaan CPU (katakanlah
uptime
) hanya dihitung dengan berapa lama proses idle berada pada CPU dan berapa lama tidak ada selama periode waktu tertentu?
PS Kemungkinan besar pertanyaan ini disebabkan oleh fakta bahwa saya tidak sepenuhnya memahami cara kerja CPU. yaitu saya mengerti perakitan, kerangka waktu dan interupsi tetapi saya tidak tahu bagaimana, misalnya, CPU dapat menggunakan energi lebih banyak atau lebih sedikit tergantung pada apa yang sedang dieksekusi. Saya akan berterima kasih jika seseorang juga dapat menjelaskan hal itu kepada saya.
sumber
Jawaban:
Tugas idle digunakan untuk proses akuntansi, dan juga untuk mengurangi konsumsi energi. Di Linux, satu tugas idle dibuat untuk setiap prosesor, dan dikunci untuk prosesor itu; setiap kali tidak ada proses lain untuk dijalankan pada CPU itu, tugas idle dijadwalkan. Waktu yang dihabiskan dalam tugas siaga muncul sebagai waktu "diam" di alat seperti
top
. (Waktu aktif dihitung secara berbeda.)Unix tampaknya selalu memiliki semacam loop menganggur (tetapi tidak selalu tugas menganggur yang sebenarnya, lihat jawaban Gilles ), dan bahkan dalam V1 itu menggunakan
WAIT
instruksi yang menghentikan prosesor hingga terjadi interupsi (singkatan dari “wait for mengganggu"). Beberapa sistem operasi lain menggunakan loop sibuk, DOS, OS / 2 , dan versi awal Windows pada khususnya. Untuk waktu yang cukup lama sekarang, CPU telah menggunakan instruksi "tunggu" semacam ini untuk mengurangi konsumsi energi dan produksi panas. Anda dapat melihat berbagai implementasi tugas-tugas idle misalnya diarch/x86/kernel/process.c
dalam kernel Linux: yang dasar hanya memanggilHLT
, yang menghentikan prosesor sampai terjadi gangguan (dan memungkinkan mode hemat energi C1), implementasi lainnya menangani berbagai bug atau ketidakefisienan ( misalnya menggunakanMWAIT
alih-alihHLT
pada beberapa CPU).Semua ini benar-benar terpisah dari status siaga dalam proses, ketika mereka sedang menunggu acara (I / O dll.).
sumber
play_dead()
adalah nama mnemonik yang sangat bagus untuk mengeksekusi HALT. Tidakkah ada risiko untuk mengirim HALT ke setiap CPU dan akibatnya hang? (yaitu mencapai situasi itu, HALT setiap CPU, akan menjadi bug di kernel yang benar?)Dalam desain buku teks dari penjadwal proses, jika penjadwal tidak memiliki proses untuk menjadwalkan (yaitu jika semua proses diblokir, menunggu input), maka penjadwal menunggu interupsi prosesor. Interupsi dapat menunjukkan input dari perangkat (aksi pengguna, paket jaringan, selesai membaca dari disk, dll.) Atau mungkin interupsi timer yang memicu timer dalam suatu proses.
Penjadwal Linux tidak memiliki kode khusus untuk case-to-do. Alih-alih, ini mengkodekan kasus tidak ada yang harus dilakukan sebagai proses khusus, proses idle. Proses idle hanya dijadwalkan ketika tidak ada proses lain yang dapat dijadwalkan (ini secara efektif memiliki prioritas yang sangat rendah). Proses idle sebenarnya adalah bagian dari kernel: ini adalah utas kernel, yaitu utas yang mengeksekusi kode dalam kernel, bukan kode dalam suatu proses. (Lebih tepatnya, ada satu utas seperti itu untuk setiap CPU.) Ketika proses siaga berjalan, ia melakukan operasi menunggu-untuk-interupsi.
Cara kerja menunggu-interupsi tergantung pada kemampuan prosesor. Dengan desain prosesor paling dasar, itu hanya lingkaran sibuk -
Prosesor terus menjalankan instruksi cabang selamanya, yang tidak menghasilkan apa-apa. Kebanyakan OS modern tidak melakukan ini kecuali mereka berjalan pada prosesor di mana tidak ada yang lebih baik, dan sebagian besar prosesor memiliki sesuatu yang lebih baik. Daripada menghabiskan energi tanpa melakukan apa-apa selain memanaskan ruangan, idealnya, prosesor harus dimatikan. Jadi kernel menjalankan kode yang memerintahkan prosesor untuk mematikan dirinya sendiri, atau setidaknya mematikan sebagian besar prosesor. Harus ada setidaknya satu bagian kecil yang tetap dihidupkan, pengontrol interupsi. Ketika periferal memicu interupsi, pengontrol interupsi akan mengirimkan sinyal pengaktifan ke bagian utama (bagian dari) prosesor.
Dalam praktiknya, CPU modern seperti Intel / AMD dan ARM memiliki banyak pengaturan manajemen daya yang kompleks. OS dapat memperkirakan berapa lama prosesor akan tetap dalam mode siaga dan akan memilih berbagai mode berdaya rendah tergantung pada ini. Mode menawarkan kompromi yang berbeda antara penggunaan daya saat idle, dan waktu yang diperlukan untuk masuk dan keluar dari mode idle. Pada beberapa prosesor, OS juga dapat menurunkan laju clock prosesor ketika menemukan bahwa proses tidak memakan banyak waktu CPU.
sumber
HLT
dapat mematikan varian SL dari 386 dan 486, sebelum DX4 keluar (artikel Wikipedia salah).Tidak, tugas idle tidak membuang siklus CPU. Penjadwal tidak memilih proses menganggur untuk dieksekusi. Proses idle sedang menunggu beberapa peristiwa terjadi sehingga itu dapat berlanjut. Misalnya, bisa menunggu input dalam
read()
panggilan sistem.Omong-omong, kernel bukanlah proses yang terpisah. Kode kernel selalu dieksekusi dalam konteks suatu proses (yah, kecuali untuk kasus khusus dari thread kernel), jadi tidak benar untuk mengatakan "dan satu CPU akan dipegang oleh kernel itu sendiri sementara tidak ada pekerjaan pengguna yang melakukan".
sumber