Teknik olarak, Erlang'daki işlemler neden OS iş parçacıklarından daha verimli?


170

Erlang Karakteristikleri

Gönderen Erlang Programlama (2009):

Erlang eşzamanlılığı hızlı ve ölçeklenebilirdir. Erlang sanal makinesinin oluşturulan her işlem için bir OS iş parçacığı oluşturmadığı için işlemleri hafiftir. Temel işletim sisteminden bağımsız olarak VM'de oluşturulur, planlanır ve işlenir. Sonuç olarak, süreç oluşturma süresi mikrosaniye mertebesinde ve eşzamanlı olarak mevcut süreçlerin sayısından bağımsızdır. Bunu, her işlem için temel bir OS iş parçacığının oluşturulduğu Java ve C # ile karşılaştırın: Erlang her iki dili de büyük ölçüde geride bıraktığında çok rekabetçi karşılaştırmalar alacaksınız.

Gönderen eşzamanlılık Erlang (pdf) içinde programlama odaklı (slaytlar) (2003):

Bir Erlang işlemi oluşturmak için geçen sürenin 1µs ila 2.500 işlem arasında sabit olduğunu gözlemliyoruz; daha sonra 30.000 işleme kadar yaklaşık 3µs'ye yükselir. Java ve C # performansı şeklin üst kısmında gösterilir. Az sayıda işlem için, bir işlem oluşturmak yaklaşık 300µs alır. İki binden fazla süreç oluşturmak imkansızdır.

30.000 işleme kadar iki Erlang işlemi arasında mesaj gönderme süresinin yaklaşık 0,8 µs olduğunu görüyoruz. C # için, maksimum işlem sayısına kadar (yaklaşık 1800 işlem) mesaj başına yaklaşık 50µs alır. Java daha da kötüydü, 100'e kadar işlem için mesaj başına yaklaşık 50µs aldı ve daha sonra yaklaşık 1000 Java işlemi olduğunda mesaj başına hızla 10 ms'ye çıktı.

Düşüncelerim

Erlang süreçlerinin neden yeni süreçlerin ortaya çıkmasında çok daha verimli olduğunu ve işlem başına daha küçük bellek ayak izlerine sahip olduklarını teknik olarak tam olarak anlamıyorum. Hem OS hem de Erlang VM, zamanlama, bağlam anahtarları yapmak ve kayıtlardaki değerleri takip etmek vb.

OS iş parçacıkları neden Erlang'daki işlemlerle aynı şekilde uygulanmaz? Daha fazla bir şeyleri desteklemeleri mi gerekiyor? Ve neden daha büyük bir bellek alanına ihtiyaç duyuyorlar? Ve neden daha yavaş yumurtlama ve iletişim var?

Teknik olarak, Erlang'daki süreçler yumurtlama ve iletişim söz konusu olduğunda neden OS iş parçacıklarından daha verimli? İşletim sistemindeki iş parçacıkları neden aynı verimli şekilde uygulanamıyor ve yönetilemiyor? İşletim sistemi iş parçacığı neden daha büyük bir bellek alanına, daha yavaş yumurtlama ve iletişime sahiptir?

Daha fazla okuma


1
Bir hipotezin neden doğru olduğunu anlamaya çalışmadan önce , hipotezin doğru olup olmadığını belirlemeniz gerekir - örneğin, kanıtlarla desteklenir. İçin başvurular var mı herhangi like-for-benzeri bir Erlang süreç aslında gösteren karşılaştırmalar olan bir yukarı güncel JVM üzerinde (diyelim) bir Java iş parçacığı daha etkilidir? Veya doğrudan OS işlemi ve iş parçacığı desteğini kullanan bir C uygulaması mı? (İkincisi benim için çok, çok olası görünmüyor. Birincisi sadece biraz muhtemel.) Yani, sınırlı bir ortamla (Francisco'nun noktası), doğru olabilir, ama sayıları görmek istiyorum.
TJ Crowder

1
@Donal: Diğer birçok mutlak ifadede olduğu gibi. :-)
TJ Crowder

1
@Jonas: Teşekkürler, ama tarih (1998-11-02) ve JVM sürümü (1.1.6) kadar var ve durdu. Sun'ın JVM'si son 11.5 yılda (ve muhtemelen Erlang'ın tercümanı da) özellikle diş açma alanında oldukça iyileşmiştir . (Açıkça söylemek gerekirse, hipotezin doğru olmadığını söylemiyorum [ve Francisco ve Donal, Erland'ın neden orada bir şeyler yapabileceğini işaret ettiler]; Yüz değerine alınmaması gerektiğini söylüyorum kontrol edilmeden.)
TJ Crowder

1
@Jonas: "... ama sanırım Erlang'da yapabilirsin ..." Bu "tahmin" kısmı dostum. :-) Erlang'ın süreç değiştirme sürecinin binlerce kişiyi geçtiğini tahmin ediyorsunuz . Java veya OS iş parçacıklarından daha iyi sonuç verdiğini tahmin ediyorsunuz . Tahmin ve yazılım geliştirici harika bir kombinasyon değildir. :-) Ama bence bu konuya değindim.
TJ Crowder

17
@TJ Crowder: erlang ve run erl +P 1000100 +hms 100yazın {_, PIDs} = timer:tc(lists,map,[fun(_)->spawn(fun()->receive stop -> ok end end) end, lists:seq(1,1000000)]).ve daha sonra sonuç için yaklaşık üç dakika bekleyin. Bu çok basit. Mine dizüstü bilgisayarda işlem başına 140us ve 1GB tüm RAM alır. Ancak doğrudan kabuk oluşturur, derlenmiş koddan daha iyi olmalıdır.
Hynek -Pichi- Vychodil

Yanıtlar:


113

Katkıda bulunan birkaç faktör vardır:

  1. Erlang süreçleri işletim sistemi işlemleri değildir. Erlang VM tarafından hafif bir kooperatif diş açma modeli kullanılarak uygulanır (Erlang seviyesinde önleyici, ancak işbirliği içinde programlanmış bir çalışma süresinin kontrolü altında). Bu, bağlamı değiştirmenin çok daha ucuz olduğu anlamına gelir, çünkü yalnızca bilinen, kontrollü noktalarda geçiş yaparlar ve bu nedenle tüm CPU durumunu (normal, SSE ve FPU kayıtları, adres alanı eşleme vb.) Kaydetmek zorunda değildirler.
  2. Erlang süreçleri, çok küçük başlayan ve gerektiğinde büyüyen dinamik olarak ayrılmış yığınlar kullanır. Bu, kullanılabilir tüm RAM'leri emmeden binlerce hatta milyonlarca Erlang işleminin doğmasına izin verir.
  3. Erlang eskiden tek iş parçacıklıydı, yani süreçler arasında iş parçacığı güvenliğini sağlamaya gerek yoktu. Şimdi SMP'yi destekliyor, ancak aynı zamanlayıcı / çekirdek üzerindeki Erlang süreçleri arasındaki etkileşim hala çok hafif (çekirdek başına ayrı çalışma kuyrukları var).

6
2. noktanıza: Ve eğer süreç henüz çalışmadıysa, yığının tahsis edilmesi için bir neden yoktur. Buna ek olarak: Bir sürecin GC'siyle uğraşarak asla hafıza toplamayacak şekilde birkaç numara çalınabilir. Ama bu gelişmiş ve biraz tehlikeli :)
ÇAPA CEVAPLARI VERİYORUM

3
3. noktanıza: Erlang değişmez verileri zorlar, bu nedenle SMP'nin sunulması iş parçacığı güvenliğini etkilememelidir.
nilskp

@ nilskp, bu doğru, erlang aynı zamanda işlevsel bir programlama dilidir. "Değişken" veri yoktur. bu da iplik güvenliğine yol açar.
liuyang1

6
@nilskp: (RE: 3. noktaya yorum yapıyorsunuz…) Dilin değişmez bir tip sistemi olmasına rağmen, temel uygulama - mesaj iletme, zamanlayıcı, vb. - tamamen farklı bir hikaye. Doğru ve verimli SMP desteği sadece bir anahtar hareketiyle gerçekleşmedi.
Marcelo Cantos

@ rvirding: Açıklayıcı ek için teşekkürler. Puanlarınızı cevabımın bedenine entegre etme özgürlüğünü aldım.
Marcelo Cantos

73

Biraz daha araştırma yaptıktan sonra Joe Armstrong'un bir sunumunu buldum.

Gönderen Erlang - eşzamanlı dünyada (sunum) için yazılım (13 dk):

[Erlang] eşzamanlı bir dildir - yani, iş parçacıklarının programlama dilinin bir parçası olduğu, işletim sistemine ait olmadığı anlamına gelir. Java ve C ++ gibi programlama dillerinde yanlış olan şey budur. İş parçacıkları programlama dilinde değil, iş parçacıkları işletim sisteminde bir şeydir - ve işletim sistemindeki tüm sorunları devralırlar. Sorunlardan biri, bellek yönetim sisteminin ayrıntı düzeyidir. İşletim sistemindeki bellek yönetimi tüm bellek sayfalarını korur, bu nedenle bir iş parçacığının olabileceği en küçük boyut bir sayfanın en küçük boyutudur. Aslında çok büyük.

Eğer makinenize daha fazla bellek eklerseniz - sayfa tabloları taneciklik artar böylece hafızayı koruyan bit aynı sayıda - Eğer birkaç yüz bayt çalışan biliyorum bir işlem için diyelim 64KB kullanarak sonunda.

Sanırım hepsi olmasa da, en azından birkaç sorum yanıtlıyor



2
Yığınlardaki bellek koruması bir nedenden dolayı var. Erlang, işlemcinin MMU'su aracılığıyla farklı yürütme bağlamlarının yığınlarını korumuyor mu? (Ve en iyisini umuyoruz?) Ya bir iplik küçük yığınından daha fazlasını kullanıyorsa? (Tüm yığın tahsisleri daha büyük bir yığının gerekip gerekmediğini görmek için kontrol ediliyor mu? Yığın hareket edebilir mi?)
Thanatos

2
@Thanatos: Erlang, programların belleğe erişmesine veya yığınla uğraşmasına izin vermez. Tüm ayırmalar, yığın ve yığın olarak yönetilen çalışma zamanından geçmelidir. Başka bir deyişle: donanım koruması işe yaramaz çünkü zaten gerçekleşemeyecek şeylere karşı koruma sağlar. Dil, işaretçi-emniyetli, yığın-emniyetli, bellek-emniyetli ve tip-emniyetlidir. Bir işlem "minik yığınından" fazlasını kullanamaz çünkü yığın gerektiği gibi büyür. Bunu küçüğün tersi olarak düşünebilirsiniz: sonsuz büyük. (Ama tembelce ayrıldı.)
Jörg W Mittag

4
Microsoft Research tarafından Tekillik İşletim Sistemine bir göz atmalısınız. Tekillikte, tüm kod, çekirdek, aygıt sürücüleri, kitaplıklar ve kullanıcı programları 0 halkasında tam çekirdek ayrıcalıklarına sahip olarak çalışır. Tüm kodlar, çekirdek, aygıt sürücüleri, kitaplıklar ve kullanıcı programları, bellek koruması olmadan tek bir düz fiziksel adres alanında çalışır. Ekip, dilin verdiği garantilerin MMU'nun sağlayabileceği garantilerden çok daha güçlü olduğunu ve aynı zamanda MMU'yu kullanmanın performansa% 30 (!!!) kadar mal olduğunu keşfetti. Peki, diliniz zaten bunu yapıyorsa neden MMU kullanıyorsunuz?
Jörg W Mittag

1
OS / 400 İşletim Sistemi aynı şekilde çalışır. Tüm programlar için yalnızca tek bir düz adres alanı vardır. Ve günümüzde kullanılan gerçek dillerin çoğu aynı güvenlik özelliklerine sahiptir (ECMAScript, Java, C♯, VB.NET, PHP, Perl, Python, Yakut, Clojure, Scala, Kotlin, Groovy, Seylan, F♯, OCaml, "Objective-C" nin "Objective" bölümü, "C ++" öğesinin "++" bölümü). Eski C kodu ve C ++ ve Objective-C'nin eski özellikleri olmasaydı, artık sanal belleğe bile ihtiyacımız olmayacaktı.
Jörg W Mittag

47

Montajcıda yardımcı program uyguladım ve performansı ölçtüm.

Erlang süreçleri olarak da adlandırılan coutinler arasında geçiş yapmak, modern bir işlemci üzerinde yaklaşık 16 talimat ve 20 nanosaniye sürer. Ayrıca, sık sık geçiş yaptığınız işlemi bilirsiniz (örnek: kuyruğunda mesaj alan bir süreç, çağrı sürecinden alıcı sürece doğrudan teslim edilebilir) uygulanabilir, böylece programlayıcı devreye girmez, bir O (1) işlemi.

İşletim sistemi iş parçacıklarını değiştirmek için yaklaşık 500-1000 nanosaniye sürer, çünkü çekirdeği çağırıyorsunuz. OS iş parçacığı zamanlayıcısı O (günlük (n)) veya O (günlük (günlük (n))) zamanında çalışabilir; bu da on binlerce, hatta milyonlarca iş parçacığınız varsa fark edilmeye başlayacaktır.

Bu nedenle, Erlang süreçleri daha hızlıdır ve daha iyi ölçeklenir, çünkü hem anahtarlamanın temel çalışması daha hızlıdır hem de zamanlayıcı daha az çalışır.


33

Erlang süreçleri (yaklaşık olarak) diğer dillerde yeşil iplikler ; süreçler arasında OS tarafından zorlanan bir ayrım yoktur. (Dil ile zorlanmış bir ayrım olabilir, ancak Erlang'ın çoğundan daha iyi bir iş yapmasına rağmen bu daha az koruma sağlar.) Çok daha hafif oldukları için çok daha yaygın olarak kullanılabilirler.

Öte yandan işletim sistemi iş parçacıkları, farklı CPU çekirdeklerinde basitçe programlanabilir ve (çoğunlukla) bağımsız CPU'ya bağlı işlemeyi destekleyebilir. İşletim sistemi süreçleri işletim sistemi iş parçacıklarına benzer, ancak daha güçlü işletim sistemi tarafından zorlanan ayırma özelliğine sahiptir. Bu yeteneklerin fiyatı, işletim sistemi iş parçacıklarının ve (hatta daha da ötesi) işlemlerin daha pahalı olmasıdır.


Farkı anlamanın bir başka yolu da şudur. Diyelim ki JVM'nin üzerine bir Erlang uygulaması yazacaksınız (özellikle çılgın bir öneri değil), o zaman her Erlang sürecinin bir durumla bir nesne olmasını sağlarsınız. Daha sonra Erlang işlemlerini çalıştıran bir Thread örnekleri havuzunuz olur (genellikle ana sisteminizdeki çekirdek sayısına göre boyutlandırılır; bu, gerçek Erlang çalışma zamanlarında BTW'de ayarlanabilir bir parametredir). Bu da yapılacak işi mevcut gerçek sistem kaynaklarına dağıtacaktır. Bir şeyler yapmanın oldukça düzgün bir yolu, ama tamamen güveniyorHer bir Erlang sürecinin çok fazla bir şey yapmadığı gerçeği. Tabii ki sorun değil; Erlang, programı yürüten genel topluluk olduğu için bu işlemlerin ağır olmasını gerektirmeyecek şekilde yapılandırılmıştır.

Birçok açıdan, asıl sorun terminolojidir. Erlang'ın süreçleri çağırdığı (ve CSP, CCS ve özellikle cal hesabındaki aynı konsepte güçlü bir şekilde karşılık gelen), C mirasına sahip dillerin (C ++, Java, C # ve diğerleri) bir işlemi veya iş parçacığını çağırır. Orada bazı benzerlikler (bütün eşzamanlı yürütülmesi hakkında bazı kavramlara dahil) ama hiçbir eşdeğerlik kesinlikle yoktur. Bu yüzden birisi size “işlem” dediğinde dikkatli olun; tamamen farklı bir şey ifade ettiğini anlayabilirler…


3
Erlang, Pi Calculus'a yakın bir yere varamaz. Pi hesabı, değişkenlere bağlanabilen kanallar üzerinde senkron olayları varsayar. Bu tür bir konsept Erlang modeline hiç uymuyor. Erlang'ın bazı mesajlara ve diğerlerine yerel olarak katılabilmesi gerekmesine rağmen, Calculus'a katılın. Onu uygulayan JErlang adında bir tez belgesi (ve projesi) vardı.
KORKUNÇ TAVSİYE VERİYORUM

Her şey pi-hesabı tam olarak ne gördüğünüze bağlıdır (ve senkron kanallar artı tampon işlemleri ile asenkron kanalları modelleyebilirsiniz).
Donal Fellows

Sadece Erlang süreçlerinin hafif olduğunu söylüyorsunuz, ancak neden daha az yer kapladığını (hafif) ve neden OS iş parçacıklarından daha iyi performansa sahip olduklarını açıklamıyorsunuz.
Jonas

1
@Jonas: Bazı görev türleri için (özellikle hesaplama-ağır görevler) OS iş parçacıkları daha iyi sonuç verir. Dikkat edin, bunlar genellikle Erlang'ın kullanıldığı görevler değildir; Erlang, çok sayıda basit iletişim görevine sahip olmaya odaklanmıştır. Bunu yapmanın kazanımlarından biri, bir parça işi teslim eden ve sonucu bekleyen bir grup görev söz konusu olduğunda, bunların hepsi tek bir işlemcideki tek bir OS iş parçacığında yapılabilir; bağlam anahtarlarına sahip.
Donal Fellows

Teorik olarak, bir OS iş parçacığını çok küçük bir yığın kullanarak ve ayrılan diğer iş parçacığına özgü kaynakların sayısını dikkatlice kontrol ederek de çok ucuz hale getirebilirsiniz, ancak bu pratikte oldukça sorunludur. (Yığın gereksinimlerini tahmin etmek biraz siyah bir sanattır.) Bunun yerine, OS iş parçacıkları özellikle daha az sayıda (CPU çekirdeği sayısı sırasına göre) ve daha önemli yaptıkları durumlarda optimum olacak şekilde tasarlanmıştır. her biri işleme miktarları.
Donal Fellows

3

Sanırım Jonas, OS iş parçacıklarını Erlang süreçleriyle karşılaştırmak için bazı sayılar istedi. Programming Erlang'ın yazarı Joe Armstrong, bir süre önce Erlang süreçlerinin OS iş parçacıklarına yumurtlamanın ölçeklenebilirliğini test etti. Erlang'da basit bir web sunucusu yazdı ve çok iş parçacıklı Apache'ye karşı test etti (Apache OS iş parçacıklarını kullandığından). 1998 yılına dayanan eski bir web sitesi var. Bu siteyi sadece bir kez bulmayı başardım. Bu yüzden bağlantı sağlayamıyorum. Ama bilgi orada. Çalışmanın ana noktası, Apache'nin 8K işlemlerin hemen altında maksimize olduğunu, elindeki Erlang sunucusunun 10K + işlemlerini ele aldığını gösterdi.


5
Bunun hakkında konuştuğunuzu düşünüyorum: sics.se/~joe/apachevsyaws.html Ama erlang'ın kerlenl ipliklerine kıyasla bu kadar verimli nasıl işlediğini sordum.
Jonas

@Jonas bağlantısı öldü. Son anlık görüntü burada
alvaro g

1
Makale şöyle dedi: "Apache yaklaşık 4.000 paralel oturumda ölüyor. Yaws hala 80.000'den fazla paralel bağlantıda çalışıyor."
Nathan Long

citeseerx.ist.psu.edu/viewdoc/… adresindeki tüm makaleye bakın. Aslında, Aplang sunucusunu durdurmak kolay olsa da, Erlang sunucusunu 16 saldırgan makine kullanarak kırmanın imkansız olduğunu kanıtladı.
Bernhard

1

Erlang tercümanı sadece kendisi için endişelenmek zorunda olduğu için, işletim sisteminin endişelenecek daha birçok şeyi vardır.


0

Bunun nedeni erlang işleminin işletim sisteminde değil, evm'de (erlang sanal makinesi) yaratılmasıdır, bu nedenle maliyet daha küçüktür.

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.