Windows'ta yeni bir süreç oluşturmak neden Linux'tan daha pahalı?


101

Bir Windows kutusunda yeni bir işlem oluşturmanın Linux'tan daha pahalı olduğunu duydum. Bu doğru mu? Birisi neden daha pahalı olduğunun teknik nedenlerini açıklayabilir ve bu nedenlerin arkasındaki tasarım kararları için herhangi bir tarihsel neden sağlayabilir mi?

Yanıtlar:


68

mweerden: NT, ilk günden itibaren çoklu kullanıcı için tasarlandı, dolayısıyla bu gerçekten bir sebep değil. Bununla birlikte, süreç yaratmanın NT üzerinde NT'de olduğundan daha az önemli bir rol oynadığı konusunda haklısınız, çünkü Unix'in aksine çoklu işlemeye göre çoklu okumayı tercih ediyor.

Rob, COW kullanıldığında çatalın nispeten ucuz olduğu doğrudur, ancak işin aslı, çatalı çoğunlukla bir exec izler. Ve bir exec tüm görüntüleri de yüklemelidir. Bu nedenle forkun performansını tartışmak, gerçeğin yalnızca bir parçasıdır.

İşlem yaratma hızını tartışırken, muhtemelen NT ile Windows / Win32 arasında ayrım yapmak iyi bir fikirdir. NT (yani çekirdeğin kendisi) gittiği sürece, süreç yaratma (NtCreateProcess) ve iş parçacığı oluşturmanın (NtCreateThread) ortalama Unix'e göre önemli ölçüde daha yavaş olduğunu düşünmüyorum. Biraz daha devam ediyor olabilir, ancak burada performans farkının birincil nedenini görmüyorum.

Bununla birlikte, Win32'ye bakarsanız, süreç oluşturmaya biraz ek yük getirdiğini fark edeceksiniz. Birincisi, CSRSS'nin LPC'yi içeren süreç oluşturma hakkında bilgilendirilmesini gerektirir. En azından kernel32'nin ek olarak yüklenmesini gerektirir ve işlemin tam teşekküllü bir Win32 işlemi olarak kabul edilmesinden önce yapılması gereken bir dizi ek defter tutma iş öğesini gerçekleştirmesi gerekir. Ve manifestoların ayrıştırılması, görüntünün bir uyumluluk şimi gerektirip gerektirmediğini kontrol etmek, yazılım kısıtlama politikalarının uygulanıp uygulanmadığını kontrol etmek, yada yada.

Bununla birlikte, bir sürecin, VA alanının ve ilk iş parçacığının ham yaratılmasına ek olarak yapılması gereken tüm bu küçük şeylerin toplamında genel bir yavaşlamayı görüyorum. Ancak başlangıçta da söylendiği gibi - çoklu görev yerine çoklu okumanın tercih edilmesi nedeniyle, bu ek masraftan ciddi şekilde etkilenen tek yazılım kötü bir şekilde taşınan Unix yazılımıdır. Her ne kadar Chrome ve IE8 gibi yazılımlar birden çok işlemin faydalarını aniden yeniden keşfettiklerinde ve sık sık başlatılıp sökülmeye başladığında bu durum değişse de ...


8
Fork'u her zaman exec () takip etmez ve insanlar yalnızca fork () ile ilgilenirler. Apache 1.3, çoğu durumda işlemler gerekmeden önce çatallansa ve bir havuzda tutulsa bile, Linux'ta fork () (exec olmadan) ve Windows'ta evreler kullanır.
Blaisorblade

5
Tabii ki, tarif ettiğiniz 'just call exec' senaryosu için tasarlanmış 'vfork' komutunu da unutmamak gerekir.
Chris Huang-Leaver

4
Bundan ciddi şekilde etkilenen başka bir yazılım türü, birden fazla işlemin koordinasyonunu içeren her türlü kabuk komut dosyasıdır. Örneğin, Cygwin'in içindeki Bash betikleri bundan büyük ölçüde zarar görüyor. Ardışık düzenlerde çok sayıda sed, awk ve grep üreten bir kabuk döngüsü düşünün. Her komut bir süreç doğurur ve her boru bir alt kabuk ve bu alt kabukta yeni bir süreç oluşturur. Unix, bu tür bir kullanım göz önünde bulundurularak tasarlandı, bu nedenle hızlı süreç oluşturma burada norm olmaya devam ediyor.
Dan Molding

5
-1. Yazılımın, süreç oluşturmayı yavaşlatan uyumluluk eksikliğiyle dolu kötü tasarlanmış bir işletim sisteminde iyi çalışmadığı için 'kötü bir şekilde taşınmış' olduğu iddiası saçma.
Miles Rout

6
@MilesRout, taşıma işleminin amacı, yazılımı, sistemin güçlü ve eksik yönleri göz önünde bulundurularak yeni bir hedef sistemde çalışacak şekilde değiştirmektir. Kötü performans gösteren taşınan yazılım , işletim sisteminin sağladığı engellerden bağımsız olarak , kötü bir şekilde taşınan yazılımdır.
Dizzyspiral

28

Unix, mevcut süreci ikiye bölen ve size birinciyle aynı olan ikinci bir işlemi veren bir çatal sistem çağrısına sahiptir (fork çağrısından dönüşü modulo). Yeni işlemin adres alanı zaten çalışmakta olduğundan, bu, Windows'ta 'CreateProcess'i çağırmaktan ve exe görüntüsünü, ilişkili dll'leri vb. Yüklemekten daha ucuz olmalıdır.

Çatal durumunda, işletim sistemi, her birinin daha sonra değiştirdikleri sayfaların kendi kopyasını almasını sağlamak için her iki yeni işlemle ilişkili bellek sayfaları için 'yazarken kopyala' anlamını kullanabilir.


22
Bu argüman sadece gerçekten çatallaştığınızda geçerlidir. Yeni bir işleme başlıyorsanız, Unix'te hala çatal ve yürütmeniz gerekir. Hem Windows hem de Unix, yazma sırasında kopyaya sahiptir. Bir uygulamanın ikinci bir kopyasını çalıştırırsanız, Windows yüklü bir EXE'i kesinlikle yeniden kullanacaktır. Açıklamanızın doğru olduğunu sanmıyorum, üzgünüm.
Joel Spolsky


Cevabıma bazı performans verileri ekledim. stackoverflow.com/a/51396188/537980 Daha hızlı olduğunu görebilirsiniz.
ctrl-alt-delor

25

JP'nin söylediğine ek olarak: ek yükün çoğu işlem için Win32 başlangıcına aittir.

Windows NT çekirdeği aslında COW çatalını destekler. SFU (Microsoft'un Windows için UNIX ortamı) bunları kullanır. Ancak, Win32 çatalı desteklemez. SFU işlemleri Win32 işlemleri değildir. SFU, Win32'ye ortogonaldir: her ikisi de aynı çekirdek üzerine inşa edilmiş ortam alt sistemleridir.

İşlem dışı LPC çağrılarına ek olarak CSRSS, XP ve daha sonra, programı uygulama uyumluluğu veritabanında bulmak için uygulama uyumluluk motoruna bir işlem dışı çağrı vardır. Bu adım, Microsoft'un performans nedenleriyle WS2003'te uyumluluk motorunu devre dışı bırakmak için bir grup ilkesi seçeneği sunmasına yetecek kadar ek yüke neden olur .

Win32 çalışma zamanı kitaplıkları (kernel32.dll, vb.) Ayrıca UNIX, SFU veya yerel işlemler için geçerli olmayan çok sayıda kayıt defteri okuma ve başlatma işlemi gerçekleştirir.

Yerel işlemlerin (ortam alt sistemi olmadan) oluşturulması çok hızlıdır. SFU, süreç oluşturma için Win32'den çok daha az şey yapar, bu nedenle süreçlerinin oluşturulması da hızlıdır.

2019 İÇİN GÜNCELLEME: Linux için LXSS: Windows Alt Sistemi ekleyin

Windows 10 için SFU'nun değiştirilmesi, LXSS ortam alt sistemidir. % 100 çekirdek modudur ve Win32'nin sahip olmaya devam ettiği IPC'lerin hiçbirini gerektirmez. Bu işlemler için sistem çağrısı, doğrudan lxss.sys / lxcore.sys'ye yönlendirilir, bu nedenle fork () veya çağrı oluşturan diğer işlem, oluşturucu için yalnızca 1 sistem çağrısına mal olur, toplam. [Örnek adı verilen bir veri alanı] tüm LX işlemlerini, iş parçacıkları ve çalışma zamanı durumunu izler.

LXSS işlemleri, Win32 işlemlerine değil yerel işlemlere dayanır. Uyumluluk motoru gibi tüm Win32'ye özgü şeyler hiç devreye girmiyor.


16

Rob Walker'ın cevabına ek olarak: Bugünlerde Native POSIX Thread Kitaplığı gibi şeylere sahipsiniz - isterseniz. Ancak uzun bir süredir unix dünyasında işi "yetkilendirmenin" tek yolu fork () kullanmaktı (ve birçok durumda hala tercih edilmektedir). örneğin bir çeşit soket sunucusu

socket_accept ()
çatal()
eğer (çocuk)
    handleRequest ()
Başka
    goOnBeingParent ()
Bu nedenle, fork uygulamasının hızlı olması gerekiyordu ve zaman içinde çok sayıda optimizasyon gerçekleştirildi. Microsoft, yeni süreçler oluşturmak ve işlemler arası iletişimin kullanılması yerine CreateThread ve hatta fiberleri onayladı. CreateProcess'i fork ile karşılaştırmanın "adil" olmadığını düşünüyorum, çünkü bunlar birbirinin yerine geçemez. Fork / exec'yi CreateProcess ile karşılaştırmak muhtemelen daha uygun olacaktır.


2
Son noktanız hakkında: fork (), CreateProcess () ile değiştirilemez, ancak Windows'un fork () uygulamasını kullanması gerektiği de söylenebilir, çünkü bu daha fazla esneklik sağlar.
Blaisorblade

Ah, Bee fiili.
acib708

Ancak Linux'ta fork + exec, MS-Windows'ta CreateThread'den daha hızlıdır. Ve Linux daha da hızlı olmak için kendi başına çatallayabilir. Bununla birlikte karşılaştırırsanız, MS daha yavaştır.
ctrl-alt-delor

13

Sanırım bu konunun anahtarı her iki sistemin tarihsel kullanımıdır. Windows (ve ondan önceki DOS) aslında kişisel bilgisayarlar için tek kullanıcılı sistemlerdi . Bu nedenle, bu sistemlerin genellikle her zaman çok fazla işlem oluşturması gerekmez; (çok) basitçe söylemek gerekirse, bir süreç yalnızca bu yalnız kullanıcı bunu istediğinde yaratılır (ve biz insanlar çok hızlı çalışmıyoruz, nispeten konuşuyoruz).

Unix tabanlı sistemler başlangıçta çok kullanıcılı sistemler ve sunuculardı. Özellikle ikincisi için, belirli işleri idare etmek için (örneğin gelen bir bağlantıyla ilgilenmek) süreçleri ayıran süreçlere (örneğin, posta veya http arka plan programı) sahip olmak nadir değildir. Bunu yapmanın önemli bir faktörü ucuz forkyöntemdir (Rob Walker'ın ( 47865 ) belirttiği gibi, başlangıçta yeni oluşturulan işlem için aynı belleği kullanır), yeni süreç ihtiyaç duyduğu tüm bilgilere anında sahip olduğundan çok faydalıdır.

En azından tarihsel olarak, Unix tabanlı sistemlerin hızlı süreç oluşturma ihtiyacının Windows sistemlerinden çok daha fazla olduğu açıktır. Bunun hala geçerli olduğunu düşünüyorum çünkü Unix tabanlı sistemler hala çok süreç odaklıyken, Windows geçmişi nedeniyle muhtemelen daha çok iş parçacığı yönelimliydi (iş parçacıkları duyarlı uygulamalar yapmak için yararlıdır).

Feragatname: Bu konuda hiçbir şekilde uzman değilim, bu yüzden yanlış anladıysam beni affet.


9

Görünüşe göre "böylesi daha iyi" gibi bir çok gerekçe var.

İnsanların "Showstopper" ı okumaktan yararlanabileceğini düşünüyorum; Windows NT'nin geliştirilmesiyle ilgili kitap.

Hizmetlerin Windows NT üzerinde bir işlemde DLL olarak çalışmasının tüm nedeni, ayrı işlemler olarak çok yavaş olmalarıdır.

Düştüyseniz ve kirliyseniz, problemin kütüphane yükleme stratejisi olduğunu görürsünüz.

Unices'de (genel olarak) Paylaşılan kitaplıklar (DLL'ler) kod kesimleri gerçekte paylaşılır.

Windows NT, yükleme işleminden sonra kitaplık kodu kesimini (ve yürütülebilir kod kesimini) değiştirdiği için işlem başına DLL'nin bir kopyasını yükler. (Verilerinizin nerede olduğunu söyler?)

Bu, kitaplıklarda yeniden kullanılamayan kod bölümleriyle sonuçlanır.

Dolayısıyla, NT süreci oluşturma aslında oldukça pahalıdır. Ve olumsuz tarafta, DLL'nin bellekte kayda değer bir tasarruf sağlamamasını, ancak uygulamalar arası bağımlılık sorunları için bir şans olmasını sağlar.

Bazen geri adım atmak ve "şimdi, bunu gerçekten berbat edecek şekilde tasarlayacak olsaydık, nasıl görünürdü?"

Bir zamanlar oldukça değişken olan gömülü bir sistemle çalıştım ve bir gün ona baktım ve mikrodalga boşluğundaki elektroniklerle birlikte bir boşluk magnetron olduğunu fark ettim. Bundan sonra onu çok daha kararlı (ve daha az mikrodalga gibi) yaptık.


3
DLL tercih edilen temel adresinde yüklendiği sürece kod bölümleri yeniden kullanılabilir. Geleneksel olarak, süreçlerinize yüklenecek, ancak bu ASLR ile çalışmayan tüm DLL'ler için çakışmayan temel adresler ayarladığınızdan emin olmalısınız.
Mike Dimmick

Tüm DLL'leri yeniden başlatmak için bir araç var, değil mi? ASLR ile ne yaptığından emin değilim.
Zan Lynx

3
Kod bölümlerinin paylaşımı ASLR özellikli sistemlerde de çalışır.
Johannes

@MikeDimmick, yani bir DLL oluşturan herkes, herhangi bir çakışma olmadığından emin olmak için işbirliği yapmak zorunda mı yoksa yüklemeden önce hepsini bir sistem düzeyinde yama mı yapıyorsunuz?
ctrl-alt-delor

9

Kısa cevap "yazılım katmanları ve bileşenleri" dir.

Windows SW mimarisi, Unix'te bulunmayan veya Unix'teki çekirdek içinde basitleştirilip işlenen birkaç ek katman ve bileşene sahiptir.

Unix'te, fork ve exec çekirdeğe yapılan doğrudan çağrılardır.

Windows'ta, çekirdek API'si doğrudan kullanılmaz, üstünde win32 ve diğer bazı bileşenler vardır, bu nedenle süreç oluşturma fazladan katmanlardan geçmeli ve ardından yeni işlem bu katmanlara ve bileşenlere başlamalı veya bağlanmalıdır.

Oldukça uzun bir süredir araştırmacılar ve şirketler, deneylerini genellikle Mach çekirdeğine dayandırarak, Unix'i belli belirsiz benzer bir şekilde parçalamaya çalıştılar ; iyi bilinen bir örnek OS X'tir . Yine de her denediklerinde, o kadar yavaşlar ki, parçaları en azından kısmen ya kalıcı olarak ya da üretim sevkiyatları için çekirdeğe geri birleştirirler.


Katmanlar her şeyi yavaşlatmaz: C de çok sayıda katman içeren bir aygıt sürücüsü yazdım. Temiz kod, okuryazar programlama, okunması kolay. Katmanlar olmadan, yüksek düzeyde optimize edilmiş derleyicide yazılmış bir sürümden (marjinal olarak) daha hızlıydı.
ctrl-alt-delor

İroni şu ki, NT çok büyük bir çekirdek (mikro çekirdek değil)
ctrl-alt-delor

2

Bazı cevaplarda MS-Windows'un bazı gerekçeleri var gibi göründüğü gibi, örn.

  • "NT kernel ve Win32 aynı şey değil. NT çekirdeğine programlıyorsanız o kadar da kötü değil ”- Doğru, ancak bir Posix alt sistemi yazmıyorsanız, kimin umrunda. Win32'ye yazacaksın.
  • "ProcessCreate ile çatalları karşılaştırmak adil değil, çünkü onlar farklı şeyler yapıyorlar ve Windows'un çatalı yok" - Doğru, Bu yüzden benzer ile karşılaştıracağım. Bununla birlikte fork'u da karşılaştıracağım, çünkü süreç izolasyonu gibi birçok kullanım durumu var (örneğin, bir web tarayıcısının her sekmesi farklı bir işlemde çalışır).

Şimdi gerçeklere bakalım, performanstaki fark nedir?

Veriler http://www.bitsnbites.eu/benchmarking-os-primitives/ adresinden özetlenmiştir .
Önyargı kaçınılmaz olduğundan, özetlerken, i7 8 çekirdekli 3.2GHz çoğu test için bunu MS-Windows Donanımı lehine yaptım
. Gnu / Linux çalıştıran Raspberry-Pi hariç

Gnu / Linux, Apple-Mac ve Microsoft'un Windows'unda çeşitli temel işlemlerin karşılaştırması (daha küçük olan daha iyidir)

MS-Windows süreci oluşturma ile Linux arasında bir karşılaştırma

Notlar: Linux'ta, forkMS-Window'un tercih ettiği yöntemden daha hızlıdır CreateThread.

Süreç oluşturma türü işlemleri için sayılar (çünkü çizelgede Linux için değeri görmek zordur).

Hız sırasına göre, en hızlıdan en yavaşa (sayılar zamandır, küçük daha iyidir).

  • Linux CreateThread 12
  • Mac CreateThread 15
  • Linux Çatal 19
  • Windows CreateThread 25
  • Linux CreateProcess (fork + exec) 45
  • Mac Fork 105
  • Mac CreateProcess (fork + exec) 453
  • Raspberry-Pi CreateProcess (fork + exec) 501
  • Windows CreateProcess 787
  • Windows CreateProcess Virüs tarayıcı 2850 ile
  • 2850'den büyük Windows Fork (CreateProcess + düzeltme ile simüle edin)

Diğer ölçümler için sayılar

  • Bir dosya oluşturmak.
    • Linux 13
    • Mac 113
    • Windows 225
    • Raspberry-Pi (yavaş SD kart ile) 241
    • Koruyucu ve virüs tarayıcı vb. İle Windows 12950
  • Bellek ayırma
    • Linux 79
    • Windows 93
    • Mac 152

1

Tüm bunlara ek olarak, Win makinesinde büyük olasılıkla bir virüsten koruma yazılımının CreateProcess sırasında devreye gireceği gerçeği var ... Bu genellikle en büyük yavaşlamadır.


1
Evet bu en büyüğü, ancak tek önemli yavaşlama değil.
ctrl-alt-delor

1

Ayrıca, Windows'daki güvenlik modelinin unix tabanlı işletim sistemlerinden çok daha karmaşık olduğunu ve bu da işlem oluşturma sırasında çok fazla ek yük getirdiğini belirtmek gerekir. Windows'ta çoklu işlemeye göre çoklu okumanın tercih edilmesinin bir başka nedeni.


1
Daha karmaşık bir güvenlik modelinin daha güvenli olmasını beklerdim; ama gerçekler aksini gösteriyor.
Lie Ryan

4
SELinux ayrıca çok karmaşık bir güvenlik modelidir ve önemli bir ek yük getirmezfork()
Spudd86

6
@LieRyan, Yazılım tasarımında (benim deneyimime göre) daha karmaşık, çok nadiren daha güvenli anlamına gelir.
Woodrow Douglass
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.