IPC performansı: İsimli Boru ve Soket


114

Herkes, adlandırılmış kanalların IPC soketlerinden daha hızlı olduğunu söylüyor. Ne kadar hızlılar? Soketleri kullanmayı tercih ederim çünkü iki yönlü iletişim yapabilirler ve çok esneklerdir, ancak önemli miktarda ise esneklik yerine hızı seçeceklerdir.


10
Kilometreniz değişecektir. :) Amaçladığınız uygulama için tipik kullanımın profilini çıkarın ve ikisinden daha iyisini seçin. Ardından anonim kanalların, diğer alanların ve ailelerin soketlerinin, semaforların ve paylaşılan bellek veya mesaj kuyruklarının (SysV ve POSIX), bir veri kelimesi içeren gerçek zamanlı sinyallerin veya her neyse profilinin profilini çıkarın. pipe(2)(er,? mkfifo(3)) kazanan olabilir, ancak deneyene kadar bilemezsiniz.
pilcrow

2
SysV mesaj kuyrukları FTW! Hızlı olup olmadıkları hakkında hiçbir fikrim yok, sadece onlar için zayıf bir noktam var.
Tom Anderson

4
Bu durumda "hız" nedir? Genel veri aktarım hızı? Veya gecikme (ilk bayt alıcıya ne kadar çabuk gelir)? Hızlı yerel veri aktarımı istiyorsanız, paylaşılan hafızayı yenmek zordur. Gecikme bir sorunsa, soru daha da ilginçleşiyor ...
Ian Ni-Lewis

Yanıtlar:


64

Öncelikle kolay yolu seçmenizi, IPC mekanizmasını dikkatlice izole etmenizi öneririm, böylece soketten boruya geçebilirsiniz, ancak kesinlikle önce soketi tercih ederim. Önceden optimize etmeden önce IPC performansının bir sorun olduğundan emin olmalısınız.

Ve IPC hızından dolayı başınız derde girerse, borudan geçmek yerine paylaşılan belleğe geçmeyi düşünmeniz gerektiğini düşünüyorum.

Bazı aktarım hızı testleri yapmak istiyorsanız, hemen hemen her tür tünel oluşturmanıza izin veren çok yönlü bir program olan socat'ı denemelisiniz .


48

Paylaşılan Bellek çözümüyle alacağınız en iyi sonuçlar .

Adlandırılmış kanallar , TCP soketlerinden yalnızca% 16 daha iyidir .

IPC kıyaslaması ile sonuçlar alınır :

  • Sistem: Linux (Linux ubuntu 4.4.0 x86_64 i7-6700K 4.00GHz)
  • Mesaj: 128 bayt
  • Mesaj sayısı: 1000000

Boru karşılaştırması:

Message size:       128
Message count:      1000000
Total duration:     27367.454 ms
Average duration:   27.319 us
Minimum duration:   5.888 us
Maximum duration:   15763.712 us
Standard deviation: 26.664 us
Message rate:       36539 msg/s

FIFO'lar (adlandırılmış kanallar) karşılaştırması:

Message size:       128
Message count:      1000000
Total duration:     38100.093 ms
Average duration:   38.025 us
Minimum duration:   6.656 us
Maximum duration:   27415.040 us
Standard deviation: 91.614 us
Message rate:       26246 msg/s

Message Queue karşılaştırması:

Message size:       128
Message count:      1000000
Total duration:     14723.159 ms
Average duration:   14.675 us
Minimum duration:   3.840 us
Maximum duration:   17437.184 us
Standard deviation: 53.615 us
Message rate:       67920 msg/s

Paylaşılan Bellek karşılaştırması:

Message size:       128
Message count:      1000000
Total duration:     261.650 ms
Average duration:   0.238 us
Minimum duration:   0.000 us
Maximum duration:   10092.032 us
Standard deviation: 22.095 us
Message rate:       3821893 msg/s

TCP soketleri karşılaştırması:

Message size:       128
Message count:      1000000
Total duration:     44477.257 ms
Average duration:   44.391 us
Minimum duration:   11.520 us
Maximum duration:   15863.296 us
Standard deviation: 44.905 us
Message rate:       22483 msg/s

Unix alan soketleri karşılaştırması:

Message size:       128
Message count:      1000000
Total duration:     24579.846 ms
Average duration:   24.531 us
Minimum duration:   2.560 us
Maximum duration:   15932.928 us
Standard deviation: 37.854 us
Message rate:       40683 msg/s

ZeroMQ karşılaştırması:

Message size:       128
Message count:      1000000
Total duration:     64872.327 ms
Average duration:   64.808 us
Minimum duration:   23.552 us
Maximum duration:   16443.392 us
Standard deviation: 133.483 us
Message rate:       15414 msg/s

1
Ayrıntılı karşılaştırma için teşekkürler. "Message Queue" ile "multiprocessing.Queue" mu demek istiyorsun?
ovunccetin

1
Message Queue, bir sistem XSI mesaj kuyruğudur ( man7.org/linux/man-pages/man0/sys_msg.h.0p.html )
chronoxor

34

Shodanex'e katılıyorum, henüz sorunlu olmayan bir şeyi zamanından önce optimize etmeye çalışıyorsunuz gibi görünüyor. Eğer sürece biliyor prizler bir darboğaz olacak, ben sadece onları kullanmayı tercih ediyorum.

Adlandırılmış kanallara yemin eden pek çok insan (her şeyin ne kadar iyi yazıldığına bağlı olarak) biraz tasarruf bulur, ancak sonunda bir IPC yanıtı için yararlı iş yapmaktan daha fazla zaman harcayan bir kod elde eder. Elbette, engellemeyen planlar buna yardımcı olur, ancak bunlar yanıltıcı olabilir. Eski kodu modern çağa getirmek için yıllar harcamak, diyebilirim ki, gördüğüm vakaların çoğunda hızlanma neredeyse sıfır.

Soketlerin sizi gerçekten yavaşlatacağını düşünüyorsanız, kilitleri nasıl kullandığınıza dikkat ederek paylaşılan hafızayı kullanarak kapıdan çıkın. Yine, gerçekte, küçük bir hızlanma bulabilirsiniz, ancak bunun bir kısmını karşılıklı dışlama kilitlerini beklerken boşa harcadığınızı fark edebilirsiniz. Futex cehennemine bir geziyi savunmayacağım ( deneyiminize bağlı olarak 2015'te artık pek de cehennem değil).

Pound için pound, soketler (neredeyse) her zaman monolitik bir çekirdek altında kullanıcı alanı IPC'ye gitmenin en iyi yoludur .. ve (genellikle) hata ayıklaması ve bakımı en kolay olanıdır.


2
belki bir gün uzak ütopik bir gelecekte, şu anda başarmak için kırılmış camın üzerinde yürüdüğümüz tüm (süreçler arası ve diğerleri) yetenekleri örtük olarak sunan tamamen yeni, modüler, modern bir çekirdeğe sahip olacağız ... ama hey .. biri hayal edebilir
Gukki5

27

Soketlerin mutlaka IP (ve TCP veya UDP) anlamına gelmediğini unutmayın. 127.0.0.1'e bağlanmaya göre gözle görülür bir performans artışı sunan UNIX soketlerini (PF_UNIX) de kullanabilirsiniz.


1
Peki ya Windows?
Pacerier

1
@Pacerier Ne yazık ki, UNIX'teki soyut ad alanıyla aynı şekilde Windows'ta yerel yuvalar oluşturamazsınız. PF_UNIX soketlerinin bu sayfada açıklanan diğer yöntemlerin çoğundan önemli ölçüde daha hızlı (>% 10) olduğunu buldum.
EntangledLoops

1
devblogs.microsoft.com/commandline/af_unix-comes-to-windows güncellemesi, Unix soketleri artık Windows 10'da mevcuttur.
eri0o


11

Hıza ihtiyacınız yoksa, prizler gitmenin en kolay yoludur!

Aradığınız şey hız ise, en hızlı çözüm, adlandırılmış borular değil, paylaşılan Bellek'tir.


8

Adlandırılmış kanallarla iki yönlü iletişim için:

  • Birkaç işleminiz varsa, iki yön için iki kanal açabilirsiniz (processA2ProcessB ve processB2ProcessA)
  • Çok sayıda işleminiz varsa, her işlem için giriş ve çıkış kanallarını açabilirsiniz (processAin, processAout, processBin, processBout, processCin, processCout vb.)
  • Ya da her zamanki gibi hibrit olabilirsiniz :)

İsimlendirilmiş boruların uygulanması oldukça kolaydır.

Örneğin, standart dosya giriş-çıkış tabanlı iletişim (fopen, fprintf, fscanf ...) sayesinde C de adlandırılmış yollarla bir proje uyguladım, çok kolay ve temizdi (eğer bu da dikkate alınacaksa).

Hatta onları java ile kodladım (seri hale getirip üzerlerine nesneler gönderiyordum!)

Adlandırılmış kanalların bir dezavantajı vardır:

  • dosya sistemine bağlı oldukları için soketler gibi birden çok bilgisayarda ölçekleme yapmazlar (paylaşılan dosya sisteminin bir seçenek olmadığı varsayılarak)

8

Soketlerle ilgili bir sorun, arabelleği boşaltmanın bir yolunun olmamasıdır. Tüm verileri toplayan ve 40 ms sonra temizleyen Nagle algoritması denen bir şey var. Yani cevap verme ise ve bant genişliği değilse, bir boru kullanmak daha iyi olabilir.

Nagle'ı TCP_NODELAY soket seçeneği ile devre dışı bırakabilirsiniz, ancak bu durumda okuma tarafı tek bir okuma çağrısında asla iki kısa mesaj almayacaktır.

Bu yüzden test edin, bunların hiçbiriyle sonuçlanmadım ve paylaşılan bellekte pthread muteks ve semafor ile bellek eşlemeli tabanlı kuyruklar uyguladım, birçok çekirdek sistemi çağrısından kaçınarak (ancak bugün artık çok yavaş değiller).


3
"Öyleyse test et" <- yaşamak için kelimeler.
Koshinae

6

Adlandırılmış kanallar ve soketler işlevsel olarak eşdeğer değildir; soketler daha fazla özellik sağlar (başlangıç ​​için çift yönlüdürler).

Hangisinin daha iyi performans göstereceğini size söyleyemeyiz, ancak önemli olmadığından kesinlikle şüpheleniyorum.

Unix etki alanı soketleri hemen hemen tcp soketlerinin yaptığını yapar, ancak sadece yerel makinede ve (belki biraz) daha düşük ek yük ile.

Bir Unix soketi yeterince hızlı değilse ve çok fazla veri aktarıyorsanız, istemciniz ve sunucunuz arasında paylaşılan belleği kullanmayı düşünün (ki bu, kurulumu çok daha karmaşıktır).

Unix ve NT'nin her ikisinin de "Adlandırılmış kanallar" vardır, ancak özellik kümesinde tamamen farklıdırlar.


1
Eğer 2 boruyu açarsanız, o zaman bidi davranışı da alırsınız.
Pacerier

4

ZeroMQ [ zmq / 0mq ] gibi hafif bir çözüm kullanabilirsiniz . Soketlerden çok daha hızlı ve kullanımı çok kolaydır.


2
Tahmin edin Amit, Martin SUSTRIK'in POSIX uyumlu bir sonraki eseri nanomsg. Her neyse, bu harika yere hoş geldiniz ve tadını çıkarın ve aktif olarak Katkıda Bulunan Üye olun.
user3666197
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.