Kenapa kita harus menunggu I / O?

28

Itu selalu diketahui bahwa operasi Disk lambat dan kami tahu alasan mengapa mereka lambat. Jadi pertanyaannya di sini adalah mengapa kita harus menunggu untuk I / O atau mengapa ada hal seperti IOWait, dll?

Maksud saya, saya perhatikan bahwa ketika Anda melakukan beberapa tugas I / O di latar belakang, komputer Anda pada dasarnya menjadi jauh lebih lambat, saya terutama memperhatikan bahwa ketika menggunakan Linux, jika Anda melakukan beberapa tugas I / O yang lebih lama , OS menjadi hampir tidak dapat digunakan sampai mereka selesai.

Memang, saya juga menemukan topik ini di sebuah artikel, ada cuplikan:

I / O wait adalah 12.1%. Server ini memiliki 8 core (via cat / proc / cpuinfo). Ini sangat dekat dengan (1/8 core = 0,125)

Jadi pada dasarnya itu berarti memperlambat komputer BANYAK, mengapa begitu? Maksudku OK, sekarang komputer normal setidaknya 2 core, kadang-kadang 4 atau kadang-kadang mereka memiliki lebih karena hyperthreading atau sesuatu seperti itu. Tetapi sekarang pertanyaannya adalah mengapa CPU sebenarnya harus tetap di sana, praktis tidak melakukan hal lain selain hanya menunggu IO? Maksud saya ide dasar atau arsitektur dari manajemen proses, sekarang saya tidak tahu apakah itu OS yang bertanggung jawab untuk itu, atau apakah itu turun ke bagian perangkat keras, tetapi harus dimungkinkan cpu untuk menunggu atau periksa secara teratur, sambil benar-benar melakukan banyak tugas lain dan hanya kembali ke proses IO ketika sudah siap. Memang, jika itu tugas yang sulit dan cpu harus menunggu, mengapa tidak t yang dikelola oleh perangkat keras lebih efisien? Seperti misalnya mungkin ada semacam cpu mini yang hanya akan menunggu dan mengirimkan sebagian kecil data ke cpu nyata segera setelah kembali ke proses dan proses akan diulang dan kami tidak akan memiliki untuk secara praktis mendedikasikan inti cpu keseluruhan untuk proses penyalinan data ... Atau akankah saya menjadi orang yang harus menciptakan hal semacam ini dan mendapatkan hadiah nobel untuk itu? : S

Sekarang oke, saya benar-benar meletakkannya sekarang dari sudut pandang pengamat dan saya benar-benar belum masuk terlalu jauh ke dalam topik, tapi saya benar-benar tidak mengerti mengapa cpu harus bekerja dengan kecepatan HDD, sementara itu bisa saja lakukan sesuatu yang lain dan kembali ke HDD setelah siap. Idenya bukan untuk mempercepat aplikasi yang membutuhkan operasi IO atau proses penyalinan atau apa pun, tetapi idenya adalah untuk secara minimal mempengaruhi konsumsi CPU saat melakukan operasi itu, sehingga OS dapat menggunakannya untuk proses lain dan pengguna tidak perlu merasakan kelambanan komputer saat melakukan operasi penyalinan ...

Arturas M
sumber
41
"Sementara itu hanya bisa melakukan sesuatu yang lain" - seperti? Perlu bekerja dengan data. Jika data itu tidak ada dalam cache L1 CPU, itu perlu mengambilnya dari cache L2. Jika tidak dalam cache L2, perlu mengambil dari L3 (jika ada). Jika tidak ada sama sekali pada cache mati, perlu mengakses memori utama. Jika tidak di memori utama ... di perlu mengakses HDD.
Oded
39
Komputer melakukan do sesuatu yang lain; kernel memblokir utas sampai operasi IO selesai, membiarkan utas / proses lain berjalan. Tetapi jika semuanya menunggu di disk IO, maka tidak ada lagi yang bisa dilakukan.
Kolonel Thirty Two
6
Anda harus menunggu program untuk mencapai menara I / O dan mengirimkan frisbee Anda!
Almo
1
@immibis Benar! :)
Almo
2
Biasanya OS modern melakukan apa yang Anda keluhkan tidak lakukan - operasi IO dikirim ke perangkat keras yang sesuai dan interupsi dihasilkan oleh perangkat keras untuk menunjukkan bahwa operasi telah dilakukan. Proses menunggu di IO biasanya diblokir sambil menunggu (ini bisa diubah). Jika banyak proses menunggu di IO dan tidak ada proses lain yang bisa dilakukan oleh CPU maka tidak banyak yang bisa dilakukan. Anda juga bisa berakhir di neraka mem-swap. Program penulisan untuk memanfaatkan CPU, memori, dan IO secara efisien memerlukan keterampilan khusus, dan apa lagi yang berjalan juga akan memengaruhi apa yang paling berhasil.
nategoose

Jawaban:

19

Skema I / O yang Anda gambarkan sedang digunakan saat ini di komputer.

mengapa CPU benar-benar harus tetap di sana, praktis tidak melakukan apa pun selain hanya menunggu IO?

Ini adalah metode yang memungkinkan I / O sederhana: diprogram I / O . Banyak sistem tertanam dan mikroprosesor low / end hanya memiliki instruksi input tunggal dan instruksi output tunggal. Prosesor harus menjalankan urutan instruksi yang eksplisit untuk setiap karakter yang dibaca atau ditulis.

tetapi harus dimungkinkan cpu untuk menunggu atau memeriksa secara teratur, sementara sebenarnya melakukan banyak tugas lain dan hanya kembali ke proses IO ketika sudah siap

Banyak komputer pribadi memiliki skema I / O lainnya. Alih-alih menunggu dalam lingkaran yang ketat untuk perangkat menjadi siap ( sibuk menunggu ), CPU memulai perangkat I / O yang meminta untuk menghasilkan interupsi ketika selesai ( interrupt driven I / O ).

Meskipun interrupt-driven I / O adalah langkah maju (dibandingkan dengan I / O yang diprogram), ini membutuhkan interupsi untuk setiap karakter yang ditransmisikan dan harganya mahal ...

Seperti misalnya mungkin ada semacam cpu mini yang hanya akan menunggu dan mengirimkan sebagian kecil data ke cpu nyata segera setelah kembali ke proses dan proses akan diulang dan kami tidak akan memiliki untuk secara praktis mendedikasikan inti cpu keseluruhan untuk proses penyalinan data ...

Solusi untuk banyak masalah terletak pada menyuruh orang lain melakukan pekerjaan! :-)

Pengontrol / chip DMA (Akses Memori Langsung) memungkinkan I / O terprogram, tetapi meminta orang lain melakukannya!

Dengan DMA, CPU hanya perlu menginisialisasi beberapa register dan bebas untuk melakukan hal lain hingga transfer selesai (dan interupsi dinaikkan).

Bahkan DMA tidak sepenuhnya gratis: perangkat kecepatan tinggi dapat menggunakan banyak siklus bus untuk referensi memori dan referensi perangkat ( siklus pencurian ) dan CPU harus menunggu (chip DMA selalu memiliki prioritas bus yang lebih tinggi).

I / O wait adalah 12.1%. Server ini memiliki 8 core (via cat / proc / cpuinfo). Ini sangat dekat dengan (1/8 core = 0,125)

Saya pikir ini dari: Memahami Disk I / O - kapan Anda harus khawatir?

Yah itu tidak aneh: sistem (mySQL) harus mengambil semua baris sebelum memanipulasi data dan tidak ada kegiatan lain.

Di sini tidak ada masalah arsitektur komputer / OS. Hanya bagaimana contohnya diatur.

Paling-paling itu bisa menjadi masalah penyetelan RDBMS atau masalah kueri SQL (indeks hilang, rencana kueri buruk, kueri buruk ...)

manlio
sumber
24

Dimungkinkan untuk menulis IO yang tidak sinkron di mana Anda memberi tahu OS untuk mengirim disk baca / tulis dan kemudian lakukan sesuatu yang lain dan kemudian periksa apakah sudah selesai. Jauh dari baru. Metode yang lebih lama menggunakan utas lainnya untuk IO.

Namun itu mengharuskan Anda melakukan sesuatu saat pembacaan itu dieksekusi dan Anda tidak akan diizinkan menyentuh buffer yang Anda berikan sebagai hasilnya.

Ini juga jauh lebih mudah untuk diprogram ketika Anda menganggap semuanya memblokir IO.

Ketika Anda memanggil fungsi baca pemblokiran, Anda tahu itu tidak akan kembali sampai sesuatu telah dibaca dan segera setelah Anda dapat mulai memprosesnya.

Loop baca yang umum adalah contoh yang bagus

//variables that the loop uses
char[1024] buffer;
while((read = fread(buffer, 1024, 1, file))>0){
    //use buffer
}

Kalau tidak, Anda perlu menyimpan status fungsi saat ini (biasanya dalam bentuk callback + userData pointer) dan meneruskannya + pengidentifikasi operasi baca kembali ke select()loop tipe. Di sana, jika operasi selesai, ia akan memetakan pengidentifikasi operasi baca ke penunjuk data + panggilan balik dan memanggil panggilan balik dengan informasi operasi yang selesai.

void callback(void* buffer, int result, int fd, void* userData){
    if(result<=0){
    //done, free buffer and continue to normal processing
    }
    //use buffer

    int readID = async_read(fd, buffer, userData->buff_size);
    registerCallback(readId, callback, userData);
}

Ini juga berarti bahwa setiap fungsi yang akhirnya dapat menggunakan async read harus dapat menangani kelanjutan async. Itu adalah perubahan non-sepele di sebagian besar program, Anda meminta orang yang mencoba masuk ke async C # tentang hal itu.


Namun sinkron IO vs asinkron IO bukan penyebab perlambatan umum. Bertukar halaman juga merupakan operasi yang perlu menunggu di IO. Penjadwal hanya akan beralih ke program lain yang tidak menunggu di IO jika ada ( IO menunggu adalah ketika prosesor sedang menganggur dan ada operasi IO yang tertunda ).

Masalah sebenarnya adalah bahwa harddisk dan CPU menggunakan saluran yang sama untuk berkomunikasi dengan RAM ; bus memori. Dan kecuali Anda menggunakan RAID maka hanya ada satu disk untuk mendapatkan data. Ini diperburuk jika Anda juga menggunakan aplikasi intensif grafis, maka komunikasi dengan GPU juga akan mengganggu.

Dengan kata lain hambatan yang sebenarnya mungkin ada di perangkat keras daripada di perangkat lunak.

ratchet freak
sumber
6
"Namun IO yang sinkron vs IO yang tidak sinkron bukanlah penyebab perlambatan umum." Jadi mengapa Anda memutuskan untuk fokus pada topik yang relatif canggih ini ketika pertanyaannya adalah tentang dasar-dasarnya?
svick
1
Anda mungkin harus menyebutkan sesuatu tentang DMA
Alec Teal
2
Fakta menyenangkan: sebenarnya ada mekanisme yang sangat lama yang memungkinkan program melakukan hal lain saat melakukan I / O tanpa harus berurusan dengan panggilan balik; itu disebut utas .
user253751
2
Diskusi yang baik tentang pro / kontra dari sync / async IO. Tetapi apakah Anda yakin itulah alasan perlambatan tersebut? Secara umum saya menemukan bahwa perlambatan di bawah beban IO yang berat pertama-tama karena perangkat lunak yang tidak dirancang dengan baik, atau ketika itu tidak terjadi karena sistem menggunakan disk tunggal, lambat (yaitu non-SSD), dan semuanya mencoba mengaksesnya secara bersamaan. . Saya akan menyalahkan bottleneck pada kemampuan disk untuk melayani permintaan sebelum saya menyalahkan pada kejenuhan dari bus memori. Anda benar - benar membutuhkan penyimpanan kelas atas untuk memenuhi bus memori modern.
aroth
9

Percayalah bahwa pemrosesan barang lain sambil menunggu I / O cukup efisien, sedekat mungkin dengan efisien. Ketika Anda melihat bahwa komputer Anda menunggu I / O hanya 12.1% dari waktu, itu berarti bahwa sebenarnya melakukan banyak hal lain secara paralel. Jika itu benar-benar harus menunggu untuk I / O tanpa melakukan hal lain, itu akan menunggu 99,9% dari waktu, itulah lambatnya I / O.

Satu-satunya cara untuk melakukan lebih banyak hal secara paralel adalah dengan memprediksi apa yang mungkin ingin dilakukan pengguna selanjutnya, dan kami belum pandai prediksi seperti itu. Jadi, jika pengguna melakukan operasi yang memerlukan sektor tertentu untuk dibaca dari hard drive, dan sektor itu belum berada di cache, maka OS akan memulai proses yang sangat lama membaca sektor itu, dan itu akan mencoba untuk melihat apakah ada hal lain yang harus dilakukan dalam waktu yang bersamaan. Jika ada pengguna lain yang menginginkan sektor yang berbeda, itu akan mengantri permintaan itu juga. Pada titik tertentu, semua permintaan telah diantrikan, dan tidak ada yang dapat kami lakukan selain menunggu yang pertama untuk dipenuhi sebelum kami dapat melanjutkan. Itu hanya fakta kehidupan.

EDIT:

Menemukan solusi untuk masalah bagaimana melakukan hal-hal lain saat melakukan I / O akan menjadi prestasi yang mengagumkan, karena pada saat yang sama akan menjadi solusi untuk masalah bagaimana melakukan hal-hal lain saat menganggur. Suatu prestasi yang luar biasa, karena itu berarti Anda akan menemukan pekerjaan yang harus dilakukan komputer Anda, sementara itu tidak ada.

Anda lihat, inilah yang terjadi: komputer Anda hanya duduk 99,99% dari waktu, tidak melakukan apa-apa. Ketika Anda memberikan sesuatu untuk dilakukan, ia pergi dan melakukannya. Jika dalam melakukannya ia harus menunggu I / O, ia duduk di sana dan menunggu. Jika ada hal lain yang harus dilakukan saat melakukan I / O, itu juga. Tetapi jika tidak ada hal lain yang harus dilakukan selain I / O, maka ia harus duduk di sana dan menunggu I / O selesai. Tidak ada cara untuk mengatasinya, selain dengan mendaftar di SETI @ Home.

Mike Nakis
sumber
Contoh 12.1% berasal dari sebuah situs web dan contoh diambil dari server dengan 8 core, ide ada hampir seluruh inti hanya dicadangkan untuk operasi itu, tentu core lainnya bebas melakukan apa saja dan dengan 8 core Anda kaya, tetapi bagaimana jika Anda hanya memiliki satu inti? : /
Arturas M
3
@ArturasM Entah Anda salah mengerti apa yang dikatakan situs web, atau penulis situs web tersebut salah paham tentang sesuatu. Komputer dengan hanya satu inti akan menghabiskan lebih sedikit waktu menunggu I / O (karena semua tugas yang tidak menunggu IO, yang mengeksekusi pada core lain sementara satu inti duduk menganggur, semua harus menjalankan pada single inti). I / O membutuhkan sejumlah waktu untuk terjadi, apakah Anda menunggu atau tidak - memiliki waktu untuk menunggu adalah gejala tidak ada hubungannya dengan waktu itu.
Random832
6

OS (kecuali itu sistem embedded tingkat sangat rendah atau sesuatu yang serupa eksotis) sudah menangani ini: jika aplikasi Anda harus menunggu untuk I / O, biasanya akan memblokir I / O itu dan beberapa utas atau aplikasi lain akan menjadi aktif. Penjadwal memutuskan yang mana.

Hanya jika tidak ada utas atau aplikasi lain yang dapat berjalan Anda sebenarnya mengumpulkan waktu tunggu. Dalam artikel yang Anda kutip (terima kasih kepada @manlio untuk tautannya), itulah masalahnya: Anda memiliki 12.1% menunggu vs. 87.4% menganggur, yang berarti satu inti sedang menunggu I / O untuk menyelesaikan sementara sisanya tidak melakukan apa-apa sama sekali. Berikan sesuatu kepada sistem untuk dikerjakan, lebih disukai beberapa hal, dan persentase tunggu akan turun.

Salah satu tujuan utama dari desain aplikasi saat ini adalah memastikan bahwa meskipun hanya ada satu aplikasi yang berjalan, dan bahkan jika aplikasi tunggal itu pada suatu titik menunggu I / O, aplikasi tersebut masih dapat melanjutkan beberapa potongan pekerjaan lainnya. Utas adalah satu pendekatan untuk ini, non-pemblokiran I / O lainnya, tetapi sangat tergantung pada jenis pekerjaan yang Anda lakukan, apakah Anda benar-benar dapat menyelesaikan sesuatu tanpa data yang Anda tunggu.

saat menggunakan Linux, jika Anda melakukan beberapa tugas I / O lagi, OS menjadi hampir tidak dapat digunakan sampai mereka selesai.

Itu biasanya merupakan indikasi dari beberapa situasi I / O-terikat. Saya berani mengatakan bahwa sistemnya tidak lambat karena tidak dapat melakukan pemrosesan CPU yang cukup. Kemungkinan besar itu lambat karena sejumlah hal bergantung pada data dari HDD, yang sedang sibuk saat itu. Ini mungkin aplikasi yang ingin Anda jalankan tetapi harus memuat file yang dapat dieksekusi, file library, ikon, font, dan sumber daya lainnya. Mungkin aplikasi yang sudah Anda jalankan, tetapi yang telah menukar sebagian dari memori mereka dan sekarang perlu ditukar lagi untuk melanjutkan. Mungkin ada beberapa daemon yang karena satu dan lain alasan berpikir bahwa itu tidak hanya harus menulis baris ke file log tetapi juga menyiram file log itu sebelum menjawab beberapa permintaan.

Anda dapat menggunakan alat seperti iotopuntuk melihat bagaimana kapasitas I / O dialokasikan untuk proses, dan ioniceuntuk menetapkan prioritas I / O untuk proses. Misalnya pada mesin desktop, Anda dapat mengklasifikasikan semua pemrosesan data massal ke idlekelas penjadwalan, sehingga saat beberapa aplikasi interaktif membutuhkan bandwidth I / O, pemrosesan massal ditangguhkan hingga aplikasi interaktif selesai.

MvG
sumber
5

Itu tergantung pada kode aplikasi Anda. Saya kira kode Anda berjalan di Linux.

Anda bisa menggunakan multi- threading (mis. POSIX pthreads ) untuk membuat utas terikat-komputasi melakukan beberapa komputasi sementara utas lain yang terikat IO sedang melakukan IO (dan menunggu). Anda bahkan dapat membuat aplikasi Anda menjalankan beberapa proses berkomunikasi dengan komunikasi antar proses (IPC), lihat pipa (7) , fifo (7) , socket (7) , unix (7) , shm_overview (7) , sem_overview (7) , mmap (2) , eventfd (2) dan baca Pemrograman Linux Lanjut dll ....

Anda dapat menggunakan IO non-blocking , misal pass O_NOBLOCKuntuk membuka (2) dll dll dll ...; maka Anda akan perlu polling (2) dan / atau menggunakan SIGIO sinyal (7) ... dan menangani EWOULDBLOCKkesalahan dari baca (2) dll ...

Anda dapat menggunakan POSIX asynchronous IO, lihat aio (7)

Untuk akses file, Anda dapat memberikan petunjuk ke halaman cache , misalnya dengan madvise (2) setelah mmap (2) dan dengan posix_fadvise (2) ; lihat juga readahead khusus Linux (2)

Tetapi Anda akhirnya akan mencapai beberapa hambatan perangkat keras (bus, RAM, dll ...). Lihat juga ionice (1)

Basile Starynkevitch
sumber
1

Saya menambahkan sudut pandang lain daripada yang lain, mungkin kontroversial:

Ini masalah khas sistem operasi Linux. Tertunda secara spesifik (Cari "Linux mouse lag"). Windows tidak memiliki masalah ini. Saya memiliki dual boot Windows 7 dan Linux Mint. Bahkan ketika melakukan operasi disk intensif di Windows, Windows terasa keras, mouse bergerak secara normal. Di Linux sebaliknya tidak terasa begitu smoots dan mouse kadang-kadang ketinggalan bahkan saat browsing web normal.

Mungkin karena filosofi dan sejarah yang berbeda dari kedua sistem ini. Windows sejak awal dirancang untuk pengguna biasa, terutama sistem operasi grafisnya. Dan untuk pengguna Windows, perilaku sistem yang tidak mulus dan gerakan menghentikan mouse adalah sinyal bahwa ada sesuatu yang salah. Jadi programmer Microsoft bekerja keras untuk merancang seluruh sistem untuk meminimalkan kasus ketika sistem terasa lambat. Sebaliknya Linux pada awalnya bukan sistem grafis, desktop hanya penambahan pihak ke-3 di sini. Dan Linux pada prinsipnya dirancang untuk peretas menggunakan baris perintah. Selesaikan semuanya dengan filosofi. Linux sama sekali tidak dirancang untuk perilaku halus dalam pikiran, perasaan tidak penting di sini.

Catatan: Saya tidak mengatakan bahwa Windows lebih baik dari Linux, saya katakan mereka hanya memiliki filosofi keseluruhan yang berbeda, yang dalam lingkungan yang kompleks dapat menyebabkan perilaku / perasaan tingkat tinggi yang berbeda dari sistem ini.

pengguna3123061
sumber
Linux mouse lag mungkin dapat dihindari atau dikurangi dengan konfigurasi sistem yang cermat (mis. Menggunakan nice& ionicepada proses yang lapar). Dan saya memang menggunakan Linux dan hampir tidak pernah mengalami tetikus Linux itu (kecuali ketika membebani komputer saya ...)
Basile Starynkevitch
BTW, Linux kebanyakan merupakan OS server.
Basile Starynkevitch
Saya akan mencatat bahwa saya telah mengalami UI dan mouse lag pada Windows 7, bahkan pada saat-saat ketika Task Manager dan Resource Monitor menunjukkan penggunaan memori yang rendah dan aktivitas CPU dan disk yang rendah.
8bittree