ประสิทธิภาพของ IPC: ชื่อว่า Pipe vs Socket


114

ดูเหมือนทุกคนจะบอกว่าท่อที่ตั้งชื่อนั้นเร็วกว่าซ็อกเก็ต IPC พวกเขาเร็วแค่ไหน? ฉันต้องการใช้ซ็อกเก็ตเพราะสามารถสื่อสารสองทางได้และมีความยืดหยุ่นมาก แต่จะเลือกความเร็วมากกว่าความยืดหยุ่นหากเป็นจำนวนมาก


10
ระยะทางของคุณจะแตกต่างกันไป :) โปรไฟล์การใช้งานทั่วไปสำหรับแอปพลิเคชันที่คุณต้องการและเลือกสิ่งที่ดีกว่าของทั้งสอง จากนั้นกำหนดโปรไฟล์ไปป์ที่ไม่ระบุชื่อซ็อกเก็ตของโดเมนและตระกูลอื่น ๆ เซมาโฟร์และหน่วยความจำที่ใช้ร่วมกันหรือคิวข้อความ (SysV และ POSIX) สัญญาณเรียลไทม์ด้วยคำของข้อมูลหรืออะไรก็ตาม pipe(2)(เอ่อmkfifo(3)?) อาจเป็นผู้ชนะ แต่คุณจะไม่รู้จนกว่าจะได้ลอง
pilcrow

2
ข้อความ SysV เข้าคิว FTW! ฉันไม่รู้ว่ามันเร็วไหมฉันแค่มีจุดอ่อนสำหรับพวกเขา
Tom Anderson

4
"ความเร็ว" ในกรณีนี้คืออะไร? อัตราการถ่ายโอนข้อมูลโดยรวม? หรือเวลาแฝง (ไบต์แรกถึงผู้รับเร็วแค่ไหน) หากคุณต้องการถ่ายโอนข้อมูลภายในเครื่องที่รวดเร็วก็ยากที่จะเอาชนะหน่วยความจำที่ใช้ร่วมกันได้ หากความล่าช้าเป็นปัญหาคำถามจะน่าสนใจมากขึ้น ...
Ian Ni-Lewis

คำตอบ:


64

ฉันขอแนะนำให้คุณใช้เส้นทางที่ง่ายก่อนแยกกลไก IPC อย่างระมัดระวังเพื่อให้คุณสามารถเปลี่ยนจากซ็อกเก็ตเป็นท่อได้ แต่ฉันจะไปกับซ็อกเก็ตก่อน คุณควรแน่ใจว่าประสิทธิภาพของ IPC เป็นปัญหาก่อนที่จะทำการเพิ่มประสิทธิภาพล่วงหน้า

และหากคุณประสบปัญหาเนื่องจากความเร็ว IPC ฉันคิดว่าคุณควรพิจารณาเปลี่ยนไปใช้หน่วยความจำที่ใช้ร่วมกันแทนที่จะไปที่ท่อ

หากคุณต้องการทดสอบความเร็วในการถ่ายโอนคุณควรลองsocatซึ่งเป็นโปรแกรมอเนกประสงค์ที่ช่วยให้คุณสร้างอุโมงค์ได้เกือบทุกประเภท


48

ผลลัพธ์ที่ดีที่สุดที่คุณจะได้รับจากโซลูชันShared Memory

ท่อที่มีชื่อดีกว่าซ็อกเก็ต TCPเพียง 16%ซ็อกเก็ต

ผลลัพธ์จะได้รับจากการเปรียบเทียบ IPC :

  • ระบบ: ลินุกซ์ (Linux ubuntu 4.4.0 x86_64 i7-6700K 4.00GHz)
  • ข้อความ: 128 ไบต์
  • จำนวนข้อความ: 1000000

มาตรฐานท่อ:

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 (ท่อที่มีชื่อ) เกณฑ์มาตรฐาน:

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 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

มาตรฐานหน่วยความจำที่ใช้ร่วมกัน:

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:

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:

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:

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
ขอบคุณสำหรับการเปรียบเทียบโดยละเอียด คุณหมายถึง "multiprocessing.Queue" กับ "Message Queue" หรือไม่?
ovunccetin

1
คิวข้อความเป็นคิวข้อความ XSI ของระบบ ( man7.org/linux/man-pages/man0/sys_msg.h.0p.html )
chronoxor

34

ฉันจะเห็นด้วยกับ shodanex ดูเหมือนว่าคุณกำลังพยายามเพิ่มประสิทธิภาพบางอย่างที่ยังไม่มีปัญหาก่อนเวลาอันควร เว้นแต่คุณจะรู้ซ็อกเก็ตจะเป็นคอขวดฉันจะใช้มัน

ผู้คนจำนวนมากที่สาบานด้วยการตั้งชื่อไปป์พบว่าประหยัดได้เล็กน้อย (ขึ้นอยู่กับว่าทุกอย่างเขียนได้ดีเพียงใด) แต่จบลงด้วยรหัสที่ใช้เวลาในการบล็อกการตอบกลับ IPC มากกว่าการทำงานที่มีประโยชน์ แน่นอนว่ารูปแบบที่ไม่ปิดกั้นช่วยได้ แต่อาจเป็นเรื่องยุ่งยาก ฉันสามารถพูดได้ว่าการใช้เวลาหลายปีในการนำรหัสเก่าเข้าสู่ยุคใหม่การเร่งความเร็วนั้นแทบจะไม่มีในกรณีส่วนใหญ่ที่ฉันเคยเห็น

หากคุณคิดว่าซ็อกเก็ตจะทำให้คุณช้าลงจริงๆให้ออกไปจากประตูโดยใช้หน่วยความจำที่ใช้ร่วมกันโดยให้ความสำคัญกับวิธีการใช้ล็อค อีกครั้งในความเป็นจริงทั้งหมดคุณอาจพบการเร่งความเร็วเพียงเล็กน้อย แต่สังเกตว่าคุณเสียส่วนหนึ่งไปกับการรอล็อกการยกเว้นซึ่งกันและกัน ฉันจะไม่สนับสนุนการเดินทางไปfutex นรก (ดีไม่ค่อนข้างนรกอีกต่อไปในปี 2015 ขึ้นอยู่กับประสบการณ์ของคุณ)

ปอนด์ต่อปอนด์ซ็อกเก็ต (เกือบ) เป็นวิธีที่ดีที่สุดในการหา IPC ของผู้ใช้ภายใต้เคอร์เนลเสาหิน .. และ (โดยปกติ) เป็นวิธีที่ง่ายที่สุดในการดีบักและบำรุงรักษา


2
บางทีสักวันในอนาคตยูโทเปียอันไกลโพ้นเราจะมีเคอร์เนลใหม่แบบโมดูลาร์ที่ทันสมัยโดยปริยายซึ่งนำเสนอความสามารถ (ระหว่างกระบวนการและอื่น ๆ ) ทั้งหมดที่เรากำลังเดินข้ามเศษแก้วเพื่อทำให้สำเร็จ ... แต่เดี๋ยวก่อน .. เราสามารถฝัน
Gukki5

27

โปรดทราบว่าซ็อกเก็ตไม่จำเป็นต้องหมายถึง IP (และ TCP หรือ UDP) คุณยังสามารถใช้ซ็อกเก็ต UNIX (PF_UNIX) ซึ่งมีการปรับปรุงประสิทธิภาพที่เห็นได้ชัดเจนเมื่อเชื่อมต่อกับ 127.0.0.1


1
แล้ว Windows ล่ะ?
Pacerier

1
@Pacerier น่าเศร้าที่คุณไม่สามารถสร้างซ็อกเก็ตโลคัลบน Windows ในลักษณะเดียวกับเนมสเปซนามธรรมบน UNIX ฉันพบว่าซ็อกเก็ต PF_UNIX เร็วกว่าวิธีอื่น ๆ ส่วนใหญ่ที่อธิบายไว้ในหน้านี้มาก (> 10%)
EntangledLoops

1
devblogs.microsoft.com/commandline/af_unix-comes-to-windows update, Unix sockets พร้อมใช้งานใน Windows 10 แล้ว
eri0o

27

บ่อยครั้งที่ตัวเลขบอกมากกว่าความรู้สึกนี่คือข้อมูลบางส่วน: ประสิทธิภาพของ Pipe vs Unix Socket (opendmx.net)(opendmx.net)

เกณฑ์มาตรฐานนี้แสดงความแตกต่างของความเร็วที่เร็วขึ้นประมาณ 12 ถึง 15% สำหรับท่อ


11

หากคุณไม่ต้องการความเร็วซ็อกเก็ตเป็นวิธีที่ง่ายที่สุด!

หากสิ่งที่คุณกำลังมองหาคือความเร็วทางออกที่เร็วที่สุดคือหน่วยความจำที่ใช้ร่วมกันไม่ใช่ไปป์ที่มีชื่อ


8

สำหรับการสื่อสารสองทางกับไปป์ที่มีชื่อ:

  • หากคุณมีกระบวนการน้อยคุณสามารถเปิดสองท่อสำหรับสองทิศทาง (processA2ProcessB และ processB2ProcessA)
  • หากคุณมีหลายกระบวนการคุณสามารถเปิดท่อเข้าและออกสำหรับทุกกระบวนการ (processAin, processAout, processBin, processBout, processCin, processCout ฯลฯ )
  • หรือจะไฮบริดก็ได้เช่นเคย :)

ท่อที่มีชื่อใช้งานได้ค่อนข้างง่าย

เช่นฉันใช้โปรเจ็กต์ใน C พร้อมไปป์ที่มีชื่อด้วยการสื่อสารตามอินพุตเอาต์พุตไฟล์มาตรฐาน (fopen, fprintf, fscanf ... ) มันง่ายและสะอาดมาก (หากเป็นเช่นนั้นก็ควรพิจารณาด้วย)

ฉันเขียนโค้ดด้วย java ด้วยซ้ำ (ฉันกำลังทำให้เป็นอนุกรมและส่งวัตถุผ่านพวกเขา!)

ท่อที่มีชื่อมีข้อเสียอย่างหนึ่ง:

  • พวกเขาไม่ได้ปรับขนาดบนคอมพิวเตอร์หลายเครื่องเช่นซ็อกเก็ตเนื่องจากพวกเขาพึ่งพาระบบไฟล์ (สมมติว่าระบบไฟล์ที่ใช้ร่วมกันไม่ใช่ตัวเลือก)

8

ปัญหาอย่างหนึ่งของซ็อกเก็ตคือพวกเขาไม่มีวิธีล้างบัฟเฟอร์ มีสิ่งที่เรียกว่าอัลกอริทึม Nagle ซึ่งรวบรวมข้อมูลทั้งหมดและล้างข้อมูลหลังจาก 40 มิลลิวินาที ดังนั้นหากเป็นการตอบสนองและไม่ใช่แบนด์วิดท์คุณอาจจะดีกว่าเมื่อใช้ไปป์

คุณสามารถปิดใช้งาน Nagle ด้วยตัวเลือกซ็อกเก็ต TCP_NODELAY แต่เมื่อสิ้นสุดการอ่านจะไม่ได้รับข้อความสั้น ๆ สองข้อความในการอ่านครั้งเดียว

ดังนั้นทดสอบฉันจบลงด้วยสิ่งนี้และใช้คิวตามการแมปหน่วยความจำด้วย pthread mutex และ semaphore ในหน่วยความจำที่ใช้ร่วมกันหลีกเลี่ยงการเรียกระบบเคอร์เนลจำนวนมาก (แต่วันนี้ไม่ช้าอีกต่อไป)


3
"ทดสอบมัน" <- คำที่จะใช้ชีวิตโดย
Koshinae

6

ท่อและซ็อกเก็ตที่มีชื่อไม่สามารถใช้งานได้เทียบเท่ากัน ซ็อกเก็ตมีคุณสมบัติเพิ่มเติม (เป็นแบบสองทิศทางสำหรับการเริ่มต้น)

เราไม่สามารถบอกคุณได้ว่าตัวไหนจะทำงานได้ดีกว่า แต่ฉันสงสัยอย่างยิ่งว่ามันไม่สำคัญ

ซ็อกเก็ตโดเมน Unix จะทำสิ่งที่ซ็อกเก็ต tcp จะทำได้ดี แต่เฉพาะในเครื่องท้องถิ่นและมีค่าโสหุ้ยที่ต่ำกว่า (อาจเล็กน้อย)

หากซ็อกเก็ต Unix ไม่เร็วพอและคุณกำลังถ่ายโอนข้อมูลจำนวนมากให้พิจารณาใช้หน่วยความจำที่ใช้ร่วมกันระหว่างไคลเอนต์และเซิร์ฟเวอร์ของคุณ (ซึ่งซับซ้อนกว่าในการตั้งค่ามาก)

Unix และ NT ทั้งคู่มี "ท่อที่มีชื่อ" แต่ชุดคุณลักษณะต่างกันโดยสิ้นเชิง


1
ถ้าคุณเปิดท่อ 2 ท่อคุณก็จะได้รับพฤติกรรม bidi ด้วย
Pacerier

4

คุณสามารถใช้โซลูชันที่มีน้ำหนักเบาเช่น ZeroMQ [ zmq / 0mq ] มันใช้งานง่ายมากและเร็วขึ้นอย่างมากจากนั้นซ็อกเก็ต


2
คุณอาจชอบเดา Amit, งานศิลปะต่อไปมาร์ติน SUSTRIK ของ - nanomsgตามมาตรฐาน อย่างไรก็ตามยินดีต้อนรับและเพลิดเพลินไปกับสถานที่ที่ยอดเยี่ยมแห่งนี้และเป็นสมาชิกที่มีส่วนร่วมอย่างกระตือรือร้น
user3666197
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.