ดูเหมือนทุกคนจะบอกว่าท่อที่ตั้งชื่อนั้นเร็วกว่าซ็อกเก็ต IPC พวกเขาเร็วแค่ไหน? ฉันต้องการใช้ซ็อกเก็ตเพราะสามารถสื่อสารสองทางได้และมีความยืดหยุ่นมาก แต่จะเลือกความเร็วมากกว่าความยืดหยุ่นหากเป็นจำนวนมาก
ดูเหมือนทุกคนจะบอกว่าท่อที่ตั้งชื่อนั้นเร็วกว่าซ็อกเก็ต IPC พวกเขาเร็วแค่ไหน? ฉันต้องการใช้ซ็อกเก็ตเพราะสามารถสื่อสารสองทางได้และมีความยืดหยุ่นมาก แต่จะเลือกความเร็วมากกว่าความยืดหยุ่นหากเป็นจำนวนมาก
คำตอบ:
ฉันขอแนะนำให้คุณใช้เส้นทางที่ง่ายก่อนแยกกลไก IPC อย่างระมัดระวังเพื่อให้คุณสามารถเปลี่ยนจากซ็อกเก็ตเป็นท่อได้ แต่ฉันจะไปกับซ็อกเก็ตก่อน คุณควรแน่ใจว่าประสิทธิภาพของ IPC เป็นปัญหาก่อนที่จะทำการเพิ่มประสิทธิภาพล่วงหน้า
และหากคุณประสบปัญหาเนื่องจากความเร็ว IPC ฉันคิดว่าคุณควรพิจารณาเปลี่ยนไปใช้หน่วยความจำที่ใช้ร่วมกันแทนที่จะไปที่ท่อ
หากคุณต้องการทดสอบความเร็วในการถ่ายโอนคุณควรลองsocatซึ่งเป็นโปรแกรมอเนกประสงค์ที่ช่วยให้คุณสร้างอุโมงค์ได้เกือบทุกประเภท
ผลลัพธ์ที่ดีที่สุดที่คุณจะได้รับจากโซลูชันShared Memory
ท่อที่มีชื่อดีกว่าซ็อกเก็ต TCPเพียง 16%ซ็อกเก็ต
ผลลัพธ์จะได้รับจากการเปรียบเทียบ IPC :
มาตรฐานท่อ:
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
ฉันจะเห็นด้วยกับ shodanex ดูเหมือนว่าคุณกำลังพยายามเพิ่มประสิทธิภาพบางอย่างที่ยังไม่มีปัญหาก่อนเวลาอันควร เว้นแต่คุณจะรู้ซ็อกเก็ตจะเป็นคอขวดฉันจะใช้มัน
ผู้คนจำนวนมากที่สาบานด้วยการตั้งชื่อไปป์พบว่าประหยัดได้เล็กน้อย (ขึ้นอยู่กับว่าทุกอย่างเขียนได้ดีเพียงใด) แต่จบลงด้วยรหัสที่ใช้เวลาในการบล็อกการตอบกลับ IPC มากกว่าการทำงานที่มีประโยชน์ แน่นอนว่ารูปแบบที่ไม่ปิดกั้นช่วยได้ แต่อาจเป็นเรื่องยุ่งยาก ฉันสามารถพูดได้ว่าการใช้เวลาหลายปีในการนำรหัสเก่าเข้าสู่ยุคใหม่การเร่งความเร็วนั้นแทบจะไม่มีในกรณีส่วนใหญ่ที่ฉันเคยเห็น
หากคุณคิดว่าซ็อกเก็ตจะทำให้คุณช้าลงจริงๆให้ออกไปจากประตูโดยใช้หน่วยความจำที่ใช้ร่วมกันโดยให้ความสำคัญกับวิธีการใช้ล็อค อีกครั้งในความเป็นจริงทั้งหมดคุณอาจพบการเร่งความเร็วเพียงเล็กน้อย แต่สังเกตว่าคุณเสียส่วนหนึ่งไปกับการรอล็อกการยกเว้นซึ่งกันและกัน ฉันจะไม่สนับสนุนการเดินทางไปfutex นรก (ดีไม่ค่อนข้างนรกอีกต่อไปในปี 2015 ขึ้นอยู่กับประสบการณ์ของคุณ)
ปอนด์ต่อปอนด์ซ็อกเก็ต (เกือบ) เป็นวิธีที่ดีที่สุดในการหา IPC ของผู้ใช้ภายใต้เคอร์เนลเสาหิน .. และ (โดยปกติ) เป็นวิธีที่ง่ายที่สุดในการดีบักและบำรุงรักษา
โปรดทราบว่าซ็อกเก็ตไม่จำเป็นต้องหมายถึง IP (และ TCP หรือ UDP) คุณยังสามารถใช้ซ็อกเก็ต UNIX (PF_UNIX) ซึ่งมีการปรับปรุงประสิทธิภาพที่เห็นได้ชัดเจนเมื่อเชื่อมต่อกับ 127.0.0.1
บ่อยครั้งที่ตัวเลขบอกมากกว่าความรู้สึกนี่คือข้อมูลบางส่วน: ประสิทธิภาพของ Pipe vs Unix Socket (opendmx.net)(opendmx.net)
เกณฑ์มาตรฐานนี้แสดงความแตกต่างของความเร็วที่เร็วขึ้นประมาณ 12 ถึง 15% สำหรับท่อ
หากคุณไม่ต้องการความเร็วซ็อกเก็ตเป็นวิธีที่ง่ายที่สุด!
หากสิ่งที่คุณกำลังมองหาคือความเร็วทางออกที่เร็วที่สุดคือหน่วยความจำที่ใช้ร่วมกันไม่ใช่ไปป์ที่มีชื่อ
สำหรับการสื่อสารสองทางกับไปป์ที่มีชื่อ:
ท่อที่มีชื่อใช้งานได้ค่อนข้างง่าย
เช่นฉันใช้โปรเจ็กต์ใน C พร้อมไปป์ที่มีชื่อด้วยการสื่อสารตามอินพุตเอาต์พุตไฟล์มาตรฐาน (fopen, fprintf, fscanf ... ) มันง่ายและสะอาดมาก (หากเป็นเช่นนั้นก็ควรพิจารณาด้วย)
ฉันเขียนโค้ดด้วย java ด้วยซ้ำ (ฉันกำลังทำให้เป็นอนุกรมและส่งวัตถุผ่านพวกเขา!)
ท่อที่มีชื่อมีข้อเสียอย่างหนึ่ง:
ปัญหาอย่างหนึ่งของซ็อกเก็ตคือพวกเขาไม่มีวิธีล้างบัฟเฟอร์ มีสิ่งที่เรียกว่าอัลกอริทึม Nagle ซึ่งรวบรวมข้อมูลทั้งหมดและล้างข้อมูลหลังจาก 40 มิลลิวินาที ดังนั้นหากเป็นการตอบสนองและไม่ใช่แบนด์วิดท์คุณอาจจะดีกว่าเมื่อใช้ไปป์
คุณสามารถปิดใช้งาน Nagle ด้วยตัวเลือกซ็อกเก็ต TCP_NODELAY แต่เมื่อสิ้นสุดการอ่านจะไม่ได้รับข้อความสั้น ๆ สองข้อความในการอ่านครั้งเดียว
ดังนั้นทดสอบฉันจบลงด้วยสิ่งนี้และใช้คิวตามการแมปหน่วยความจำด้วย pthread mutex และ semaphore ในหน่วยความจำที่ใช้ร่วมกันหลีกเลี่ยงการเรียกระบบเคอร์เนลจำนวนมาก (แต่วันนี้ไม่ช้าอีกต่อไป)
ท่อและซ็อกเก็ตที่มีชื่อไม่สามารถใช้งานได้เทียบเท่ากัน ซ็อกเก็ตมีคุณสมบัติเพิ่มเติม (เป็นแบบสองทิศทางสำหรับการเริ่มต้น)
เราไม่สามารถบอกคุณได้ว่าตัวไหนจะทำงานได้ดีกว่า แต่ฉันสงสัยอย่างยิ่งว่ามันไม่สำคัญ
ซ็อกเก็ตโดเมน Unix จะทำสิ่งที่ซ็อกเก็ต tcp จะทำได้ดี แต่เฉพาะในเครื่องท้องถิ่นและมีค่าโสหุ้ยที่ต่ำกว่า (อาจเล็กน้อย)
หากซ็อกเก็ต Unix ไม่เร็วพอและคุณกำลังถ่ายโอนข้อมูลจำนวนมากให้พิจารณาใช้หน่วยความจำที่ใช้ร่วมกันระหว่างไคลเอนต์และเซิร์ฟเวอร์ของคุณ (ซึ่งซับซ้อนกว่าในการตั้งค่ามาก)
Unix และ NT ทั้งคู่มี "ท่อที่มีชื่อ" แต่ชุดคุณลักษณะต่างกันโดยสิ้นเชิง
คุณสามารถใช้โซลูชันที่มีน้ำหนักเบาเช่น ZeroMQ [ zmq / 0mq ] มันใช้งานง่ายมากและเร็วขึ้นอย่างมากจากนั้นซ็อกเก็ต
nanomsg
ตามมาตรฐาน อย่างไรก็ตามยินดีต้อนรับและเพลิดเพลินไปกับสถานที่ที่ยอดเยี่ยมแห่งนี้และเป็นสมาชิกที่มีส่วนร่วมอย่างกระตือรือร้น
pipe(2)
(เอ่อmkfifo(3)
?) อาจเป็นผู้ชนะ แต่คุณจะไม่รู้จนกว่าจะได้ลอง