Neden G / Ç için beklememiz gerekiyor?


28

Disk işlemlerinin yavaş olduğu her zaman biliniyor ve neden yavaş olduklarını biliyoruz. Öyleyse buradaki soru, neden G / Ç için beklememiz gerektiği veya neden IOWait, vs. gibi bir şey olduğu?

Demek istediğim, arka planda bazı G / Ç görevlerini yaparken, bilgisayarınızın temelde daha da yavaşladığını fark ettim, özellikle Linux kullanırken, eğer biraz daha uzun süre G / Ç görevleri yapıyorsanız bunu fark ettim. , işletim sistemi tamamlanana kadar neredeyse kullanılamaz hale geliyor.

Aslında, bu konuyu bir makalede de buldum, bir snippet var:

G / Ç beklemesi% 12,1'dir. Bu sunucunun 8 çekirdeği vardır (cat / proc / cpuinfo aracılığıyla). Bu çok yakındır (1/8 çekirdek = 0.125)

Yani temelde bu, bilgisayarı bir LOT yavaşlatıyor demektir, neden? Demek istediğim, normal bilgisayar şu anda en az 2 çekirdekli, bazen 4 ya da bazen aşırı okuyuculuk ya da öyle bir şey yüzünden daha çok var. Ama şimdi soru, CPU'nun aslında neden orada kalması gerektiği, pratikte sadece IO'yu beklemekten başka bir şey yapmaması? Süreç yönetiminin temel fikri ya da mimarisini kastediyorum, şimdi bundan sorumlu olan bir işletim sistemi olup olmadığını veya donanım kısmına inip gelmediğini bilmiyorum, ancak cpu'nun beklemesi veya beklemesi mümkün olmalı aslında birçok başka görevi yerine getirirken ve yalnızca hazır olduğunda IO sürecine geri dönerken düzenli olarak kontrol edin. Gerçekten, eğer bu kadar zor bir görevse ve işlemci beklemek zorunda kalırsa, neden olmasın? donanımdan daha verimli bir şekilde yönetildi mi? Mesela, onu bekleyecek ve verinin küçük bir kısmını işleme geri döndüğü anda gerçek CPU'ya ulaştırmak için bir çeşit mini işlemci olabilir ve böylece süreç tekrarlanacak ve elimizde olmazdı. pratik olarak veri kopyalama işlemi için bütün bir cpu çekirdeği ayırmak için ... Yoksa bu tür şeyleri icat edip nobel ödülü alacak olan ben olur muyum? : S

Şimdi tamam, gerçekten şimdi gözlemcilerin bakış açısından koyuyorum ve gerçekten bu konunun derinliklerine girmedim, ancak cpu'nun neden sadece HDD'nin hızı ile çalışması gerektiğini anlamıyorum. başka bir şey yapın ve hazır olunca HDD'ye geri dönün. Buradaki fikir, IO işlemine ya da kopyalama işlemine ihtiyaç duyan uygulamayı ya da her neyse onu hızlandırmak değildir, ancak fikir bu işlemi gerçekleştirirken CPU tüketimini en az düzeyde etkilemektir, böylece işletim sistemi diğer işlemler ve kullanıcı için faydalanabilir. bazı kopyalama işlemlerini yaparken genel bilgisayarın geciktiğini hissetmenize gerek kalmayacaktı ...


41
"Sadece başka bir şey yapabilirken" - Mesela? Veri ile çalışması gerekiyor. Bu veriler CPU L1 önbelleğinde yoksa, L2 önbelleğinden alması gerekir. L2 önbelleğinde değilse, L3'ten (varsa) getirmesi gerekir. Tüm önbelleklerde hiç değilse, ana belleğe erişmesi gerekir. Ana bellekte değilse ... içinde HDD’ye erişilmesi gerekir.
08:

39
Bilgisayar yapar başka do şey; çekirdek, IO işlemi tamamlanıncaya kadar ipliği bloke eder, diğer dişlerin / işlemlerin çalışmasına izin verir. Fakat her şey diskte IO bekliyorsa, yapacak başka bir şey yoktur.
Albay Otuz İkili

6
Programların G / Ç kulesine ulaşmasını ve frizbilerini göndermesini beklemelisin!
Almo

1
@ immibis Doğru! :)
Almo

2
Tipik olarak modern işletim sistemleri yapmadıklarından şikayet ettiğiniz şeyi yapar - IO işlemleri uygun donanıma gönderilir ve işlemlerin yapıldığını belirtmek için donanım tarafından kesmeler üretilir. IO'da bekleyen işlemler genellikle beklerken engellenir (bu değiştirilebilir). Pek çok işlem IO'da bekliyorsa ve başka hiçbir işlemde CPU'nun yapması gereken hiçbir şey yoksa, yapılacak çok şey yoktur. Aynı zamanda mem-takas cehenneme de son verebilirsin. CPU, bellek ve IO'yu verimli bir şekilde kullanabilmek için programlar yazmak özel beceriler gerektirir ve başka şeyler de çalışırsa, en iyi olanı etkiler.
nategoose

Yanıtlar:


19

Tanımladığınız G / Ç şemaları bilgisayarlarda şu anda kullanımda.

Neden CPU aslında orada kalmak zorunda, pratik olarak sadece IO'yu beklemekten başka bir şey yapmıyor?

Bu mümkün olan en basit G / Ç yöntemidir: programlanmış G / Ç . Pek çok gömülü sistem ve düşük / son mikroişlemci yalnızca bir giriş talimatına ve tek bir çıkış talimatına sahiptir. İşlemci okunan veya yazılan her karakter için açık bir talimat dizisi yürütmelidir.

ancak cpu'nun beklemesi veya düzenli olarak kontrol etmesi mümkün olmalı, gerçekte başka birçok görevi yerine getirmesi ve sadece hazır olduğunda IO sürecine geri dönmesi mümkün olmalı

Birçok kişisel bilgisayarda başka G / Ç şemaları bulunur. Cihazın hazır hale gelmesi için sıkı bir döngüde beklemek yerine ( meşgul beklemede ), CPU, I / O cihazını başlattığında bir kesinti oluşturmasını ister ( kesme G / Ç ile kesme ).

Kesmeli G / Ç bir adım ileri olmasına rağmen (programlanmış G / Ç ile karşılaştırıldığında), iletilen her karakter için bir kesinti gerektirir ve pahalı ...

Mesela, onu bekleyecek ve verinin küçük bir kısmını işleme geri döndüğü anda gerçek CPU'ya ulaştırmak için bir çeşit mini işlemci olabilir ve böylece süreç tekrarlanacak ve elimizde olmazdı. pratik olarak veri kopyalama işlemi için bütün bir cpu çekirdeği ayırmak ...

Birçok sorunun çözümü, işin başkasının yapılmasında yatmaktadır! :-)

DMA denetleyicisi / yongası (Doğrudan Bellek Erişimi) programlanmış G / Ç'ye izin verir, ancak başkasının yapmasını sağlar!

DMA ile CPU sadece birkaç kayıt işlemini başlatmak zorundadır ve aktarım tamamlanıncaya kadar (ve bir kesinti ortaya çıkıncaya kadar) başka bir şey yapmak ücretsizdir.

DMA bile tamamen ücretsiz değil: yüksek hızlı cihazlar bellek referansları ve cihaz referansları ( döngü çalma ) için birçok veri yolu çevrimi kullanabilir ve CPU beklemelidir (DMA yongası her zaman daha yüksek veri yolu önceliğine sahiptir).

G / Ç beklemesi% 12,1'dir. Bu sunucunun 8 çekirdeği vardır (cat / proc / cpuinfo aracılığıyla). Bu çok yakındır (1/8 çekirdek = 0.125)

Sanırım şudur: Disk G / Ç'yi Anlamak - Ne zaman endişelenmelisiniz?

Garip değil: sistem (mySQL) verileri değiştirmeden önce tüm satırları getirmeli ve başka aktiviteler yoktur.

Burada bir bilgisayar mimarisi / işletim sistemi sorunu yok. Sadece örnek bu şekilde ayarlandı.

En fazla bir RDBMS ayarlama problemi veya bir SQL sorgu problemi (eksik indeks, hatalı sorgu planı, hatalı sorgu ...) olabilir.


24

İşletim sistemine bir disk okuma / yazma gönderme ve ardından başka bir şey yapma ve daha sonra bitmiş olup olmadıklarını kontrol etme talimatı verdiğiniz bir asenkron IO yazmak mümkündür. Yeni olmaktan uzak. Eski bir yöntem, IO için başka bir iş parçacığı kullanıyor.

Bununla birlikte, bu okuma yapılırken yapacak bir şeyin olmasını gerektirir ve sonuç için ilettiğiniz tampon belleğe dokunmanıza izin verilmez.

Ayrıca, her şeyin GÇ'yi engellediğini varsaydığınızda programlamak çok daha kolaydır.

Engelleyici bir okuma işlevini çağırdığınızda, bir şey okunana kadar ve üzerinde çalışmaya başlamanızdan hemen sonra geri dönmeyeceğini biliyorsunuzdur .

Tipik okuma döngüsü iyi bir örnek

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

Aksi halde, geçerli işlev durumunu kaydetmeniz (genellikle bir geri çağırma + userData pointer şeklinde) ve okuma işleminin + tanımlayıcısını tekrar bir select()tür döngüsüne geçirmeniz gerekir . Bir işlem bittiğinde, okuma işleminin tanımlayıcısını geri arama + veri işaretçisine eşler ve geri arama işlemini tamamlanan işlemin bilgisiyle çağırır.

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);
}

Bu, aynı zamanda, bu zaman uyumsuz okumayı kullanarak sona erebilecek her işlevin, zaman uyumsuz bir devam etmeyi kaldırabilmesi gerektiği anlamına gelir. Bu, çoğu program için önemsiz bir değişikliktir, sizden insanlardan bununla ilgili olarak asenkron C # kullanmaya çalışmasını isteyin.


Bununla birlikte, senkronize IO ve asenkron IO genel yavaşlamanın nedeni değildir. Sayfaların değiştirilmesi de GÇ'de beklemesi gereken bir işlemdir. Zamanlayıcı, eğer varsa, IO'da beklemeyen başka bir programa geçecektir ( IO beklemek, işlemci boşta iken ve bekleyen bir IO işlemi olduğunda ).

Asıl sorun, hem sabit sürücünün hem de CPU'nun RAM ile iletişim kurmak için aynı kanalı kullanmasıdır ; Hafıza veriyolu. RAID kullanmıyorsanız, verileri almak için yalnızca tek bir disk vardır. Ayrıca grafik yoğun bir uygulama kullanıyorsanız, GPU ile iletişim de karışacaktır.

Başka bir deyişle, gerçek tıkanıklık muhtemelen yazılımdan çok donanımdadır.


6
"Ancak senkronize IO'ya karşı senkronize olmayan IO genel yavaşlamanın nedeni değil." Öyleyse, soru temel konulara gelince neden bu nispeten ileri konuya odaklanmaya karar verdiniz?
svick

1
Muhtemelen DMA
Alec Teal

2
Eğlenceli gerçek: Aslında geri aramalarla uğraşmak zorunda kalmadan programların G / Ç yaparken başka bir şey yapmasını sağlayan gerçekten eski bir mekanizma var; dendiğini ipler .
user253751

2
Sync / async IO'nun artıları / eksileri hakkında iyi tartışma. Ama yavaşlamanın sebebinin bu olduğuna emin misin? Genel olarak, ağır IO yükü altındaki yavaşlamaların, ilk olarak kötü amaçlı olmayan yazılımlar nedeniyle ya da durum böyle olmadığında, sistemin tek, yavaş bir disk kullandığı (SSD olmayan) olduğu için her şey aynı anda erişmeye çalıştığını biliyorum. . Bellek veriyolunun doygunluğundan dolayı suçlamadan önce diskin isteklerini yerine getirme becerisi üzerindeki bir tıkanıklığı suçlardım. Modern bir bellek veriyolunu doyurmak için gerçekten yüksek kaliteli depolama alanlarına ihtiyacınız var .
15’te,

9

G / Ç için beklerken diğer şeylerin işlenmesinin, olabildiğince düzene yakın oldukça düzenli olduğuna inancınız olsun. Bilgisayarınızın G / Ç'yi yalnızca% 12,1 oranında beklediğini gördüğünüzde, aslında paralel olarak birçok başka şey yapıyor demektir. Başka bir şey yapmadan gerçekten G / Ç'yi beklemiş olsaydı, zamanın% 99.9'unu bekliyor olurdu, bu G / Ç'nin ne kadar yavaş olduğu.

Paralel olarak daha fazla şey yapmanın tek yolu, kullanıcının daha sonra ne yapmak isteyebileceğini tahmin etmektir ve bu tür bir tahminde henüz çok iyi değiliz. Dolayısıyla, kullanıcı sabit diskten okunması gereken belirli bir sektör gerektiren bir işlem gerçekleştiriyorsa ve o sektör önbellekte bulunmuyorsa, işletim sistemi o sektörü okumaya çok uzun bir süre başlayacaktır ve bu Bu arada yapacak başka bir şey olup olmadığını görmeye çalışacağım. Farklı bir sektör isteyen başka bir kullanıcı varsa, bu isteği de sıraya koyar. Bir noktada, tüm talepler kuyruğa alındı ​​ve yapabileceğimiz hiçbir şey yok, ancak devam etmeden önce, birincisinin gerçekleşmesini beklemekten başka bir şey yok. Bu sadece hayatın bir gerçeğidir.

DÜZENLE:

G / Ç yaparken başka şeylerin nasıl yapılacağı sorununa bir çözüm bulmak takdire şayan bir başarı olacaktır, çünkü aynı zamanda boşta iken başka şeylerin nasıl yapılacağı sorununa da bir çözüm olacaktır. Olağanüstü bir başarı, çünkü hiçbir şey yapmadan, bilgisayarınız için iş bulacağınız anlamına geliyor.

Görüyorsunuz, olan bu: Bilgisayarınız zamanın% 99,99'unu oturuyor, hiçbir şey yapmıyor. Yapacak bir şey verdiğinizde, gider ve yapar. Bunu yaparken G / Ç'yi beklemesi gerekiyorsa, orada oturur ve bekler. G / Ç yaparken yapacak başka bir şeyi varsa, o da yapar. Ancak, G / Ç dışında başka yapacak bir şeyi yoksa, orada oturmak ve G / Ç'nin tamamlanmasını beklemek zorundadır. SETI @ Home'a ​​kaydolmaktan başka, onunla uğraşmanın bir yolu yok.


% 12,1'lik örnek bir web sitesindeydi ve örnek 8 çekirdekli bir sunucudan alındı, bu işlem için neredeyse bir çekirdeğin sadece bir çekirdeğe ayrıldığı, diğer çekirdeğin herhangi bir şey yapmadan ve 8 çekirdekli olduğundan emin olduğu fikri. iyisin, ama ya sadece tek bir çekirdeğin varsa? : /
Arturas M

3
@ArturasM Ya web sitesinin ne dediğini yanlış anladınız ya da web sitesinin yazarı bir şeyi yanlış anladı. Yalnızca tek çekirdekli bir bilgisayar G / Ç için beklemek için daha az zaman harcar (GÇ'yi beklemeyen, diğer çekirdekte yürüten tüm işlemlerin tek çekirdekte boş dururken yürütmesi gerekir. çekirdek). G / Ç, bekleseniz de beklemeseniz de, belli bir süre alır - beklemek için zamana sahip olmak, o zamanla ilgisi olmamasının bir belirtisidir.
Random832

6

İşletim sistemi (çok düşük seviyeli bir gömülü sistem veya benzer şekilde egzotik bir şey değilse) zaten bununla ilgileniyor: Uygulamanız G / Ç için beklemek zorunda kalırsa, genellikle bu G / Ç'yi engeller ve diğer bazı iş parçacığı veya uygulamaları aktif. Zamanlayıcı hangisine karar verir.

Varsa sadece var hayır aslında bekleme süresini biriken olduğunuzu çalışıyor olabilir diğer iplik veya uygulama. Gelen yazıda size aktardığı sen 12.1% dinlenme hiçbir şey yapmıyor iken I / O tamamlamak için bir çekirdek bekliyor demektir% 87.4 boşta, vs bekleyen: olgu olduğunu, (bağlantıdan @manlio sayesinde) hiç. Bu sisteme yapılacak bir şey verin, tercihen birden fazla şey, ve bekleme yüzdesi düşmelidir.

Bugünün uygulama tasarımının en yüksek hedeflerinden biri, çalışan tek bir uygulama olsa bile ve bu tek bir uygulama G / Ç için bekleyen bir noktada olsa bile, uygulamanın başka bir çalışma grubuna devam edebilmesini sağlamaktır. Konular buna bir yaklaşımdır, engellemeyen G / Ç bir başkasıdır, ancak aslında beklediğiniz veriler olmadan bir şey yapıp yapamayacağınıza, yaptığınız işe bağlı olarak değişir.

Linux kullanırken, daha uzun G / Ç görevleri yapıyorsanız, işletim sistemi tamamlanana kadar neredeyse kullanılamaz duruma gelir.

Bu genellikle bazı G / Ç bağlı durumlarının bir göstergesidir. Sistemin yavaşlamadığını söylemeye cüret ediyorum çünkü yeterince işlemciyi yapamıyor. Büyük olasılıkla yavaştır, çünkü bir çok şey o sırada meşgul olan HDD’deki verilere bağlıdır. Bu, çalıştırmak istediğiniz ancak çalıştırılabilir dosyalarını, kitaplık dosyalarını, simgeleri, yazı tiplerini ve diğer kaynaklarını yüklemesi gereken uygulamalar olabilir. Halihazırda çalıştırdığınız, ancak hafızasının bir bölümünü değiştiren ve şimdi devam etmek için tekrar takılan olan uygulamalar olabilir. Bir nedenden dolayı veya başka bir sebeple, bir günlük dosyasına sadece bir satır yazması gerektiğini değil, bazı istekleri cevaplamadan önce bu günlük dosyasını yıkadığını düşünen bazı daemon olabilir.

iotopG / Ç kapasitesinin süreçlere nasıl tahsis edildiğini görmek ve işlemler ioniceiçin G / Ç önceliklerini belirlemek gibi araçlar kullanabilirsiniz . Örneğin, bir masaüstü bilgisayarında, tüm toplu veri işlemeyi idlezamanlama sınıfına göre sınıflandırabilirsiniz , böylece bazı etkileşimli uygulamaların G / Ç bant genişliği gerektirdiği anda, toplu işlem etkileşimli uygulama tamamlanıncaya kadar askıya alınır.


5

Uygulama kodunuza bağlıdır. Diyelim ki kodunuz Linux'ta çalışıyor.

Hesaplama iş parçacığı bazı hesaplama yapmak için çok iş parçacığı (örneğin POSIX pthreads ) kullanabilirsiniz, diğer IO bağlı iş parçacıkları IO (ve bunun için beklerken). Uygulamanızın süreçler arası iletişim (IPC) ile iletişim kuran birkaç işlemi çalıştırmasını bile sağlayabilir , bkz. Pipe (7) , fifo (7) , soket (7) , unix (7) , shm_overview (7) , sem_overview (7) , mmap (2) , eventfd (2) ve Gelişmiş Linux Programlama vb.

Sen kullanabilirsiniz IO engellenmeyen geçmesi örneğin O_NOBLOCKüzere açın (2) vs vs vs ...; sonra (2) ' yi yoklamanız ve / veya SIGIO sinyal kullanmanız (7) ... ve EWOULDBLOCKhatayı okuma (2) vb.

Asenkron IO POSIX kullanabilirsiniz, bkz aio (7)

Dosya erişimi için sayfa önbelleğine ipuçları verebilir , örneğin mmap (2) 'den sonra madvise (2) ve posix_fadvise (2) ; ayrıca bakınız Linux özel okuma kablosu (2)

Ama sonunda bazı donanım darboğazlarına ulaşacaktınız (otobüs, RAM vb.). Ayrıca bakınız ionice (1)


1

Diğerlerinden başka bakış açıları ekliyorum, belki tartışmalı:

Linux işletim sistemlerinin tipik sorunu. Özellikle Gecikme ("Linux fare gecikmesi" için arama yapın). Windows'un bu sorunu yok. Windows 7 ve Linux Mint çift çizme var. Windows'ta yoğun disk işlemi yaparken bile, Windows daha yumuşak hisseder, fare normal şekilde hareket eder. Linux muhaliflerinde, normal web taramaları sırasında bile pürüzsüz ve fare bazen gecikme hissetmiyor.

Muhtemelen bu iki sistemin farklı felsefesi ve tarihi. Windows, temelde grafik işlem sistemleri olan sıradan kullanıcılar için tasarlanmaya başlanmıştır. Windows kullanıcıları için, düzgün olmayan sistem davranışları ve fare hareketini durdurma bir şeyin yanlış olduğunu gösterir. Bu nedenle Microsofts programcıları, sistemler yavaş hissettiklerinde vakaları en aza indirmek için bütün sistemi tasarlamak için çok çalıştı. Tersine Linux başlangıçta grafik sistemi değildir, masaüstü burada sadece 3. taraf ekidir. Ve Linux esasen komut satırı kullanan bilgisayar korsanları için tasarlanmıştır. İşlerin felsefesini tamamlayın. Linux sadece akılda kalıcı davranış için tasarlanmamıştır, duygular burada önemli değil.

Not: Windows'un Linux'tan daha iyi olduğunu söylemiyorum, sadece karmaşık bir ortamda bu sistemlerin farklı üst düzey davranışlarına / hislerine yol açabilecek farklı bir felsefeye sahip olduklarını söylüyorum.


Linux fare lag muhtemelen kaçınılması veya sistemin dikkatli yapılandırma tarafından azaltılabileceğine inanıyordu (yani. Kullanarak niceve ioniceaç süreçler üzerinde). Ve Linux kullanıyorum ve neredeyse hiç Linux fare gecikmesi yaşamadım (bilgisayarıma aşırı yüklenme durumu hariç ...)
Basile Starynkevitch 30:15

BTW, Linux çoğunlukla bir sunucu işletim sistemidir.
Basile Starynkevitch 30:15

Görev Yöneticisi ve Kaynak İzleyicisi düşük bellek kullanımı ve düşük CPU ve disk etkinliği gösterdiğinde bile, Windows 7'de kullanıcı arayüzü ve fare gecikmesi yaşadığımı fark edeceğim.
8,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.