Производительность IPC: Named Pipe vs Socket

Кажется, что именованные каналы быстрее, чем сокеты IPC. Насколько они быстрее? Я бы предпочел использовать сокеты, потому что они могут делать двустороннюю связь и очень гибкие, но будут выбирать скорость по гибкости, если она на значительную сумму.

Ответ 1

Я бы предложил сначала сначала пройти легкий путь, тщательно изолировав механизм ipc, чтобы вы могли перейти от сокета к каналу, но я бы определенно пошел с сокет первым. Вы должны быть уверены, что производительность IPC является проблемой перед превентивной оптимизацией.

И если у вас возникают проблемы из-за скорости IPC, я думаю, вам стоит подумать о переключении на общую память, а не на трубку.

Если вы хотите провести некоторое тестирование скорости передачи, вы должны попробовать socat, что является очень универсальной программой, которая позволяет создавать почти любой туннель.

Ответ 2

Я согласен с Shodanex, похоже, вы преждевременно пытаетесь оптимизировать то, что еще не является проблематичным. Если вы не знаете, что гнезда станут узким местом, я бы просто использовал их.

Многие люди, которые ругаются по именованным каналам, находят небольшую экономию (в зависимости от того, насколько хорошо написано все остальное), но в итоге получают код, который тратит больше времени на блокировку ответа IPC, чем на полезную работу. Конечно, неблокирующие схемы помогают в этом, но они могут быть хитрыми. Я могу сказать, что потратив годы на то, чтобы перенести старый код в современную эпоху, в большинстве случаев, которые я видел, это ускорение почти равно нулю.

Если вы действительно думаете, что сокеты будут замедлять вас, то выходите из шлюза, используя общую память, внимательно следя за тем, как вы используете блокировки. Опять же, в действительности вы можете обнаружить небольшое ускорение, но обратите внимание, что вы тратите часть этого времени на ожидание взаимных исключающих блокировок. Я не собираюсь выступать за поездку в ад futex (ну, не совсем, в 2015 году, в зависимости от вашего опыта).

Фунт за фунт, сокеты (почти) всегда лучший способ использовать пользовательское пространство IPC под монолитным ядром... и (обычно) самый простой для отладки и обслуживания.

Ответ 3

Имейте в виду, что сокеты не обязательно означают IP (и TCP или UDP). Вы также можете использовать UNIX-сокеты (PF_UNIX), которые обеспечивают заметное улучшение производительности при подключении к 127.0.0.1

Ответ 4

Как часто цифры говорят больше, чем чувства, вот некоторые данные: Pipe vs Unix Socket Performance (opendmx.net).

Этот показатель показывает разницу в скорости на трубах на 12-15%.

Ответ 5

Если вам не нужна скорость, сокеты - это самый простой способ!

Если вы ищете скорость, самым быстрым решением является общая память, а не именованные каналы.

Ответ 6

Для двусторонней связи с именованными каналами:

  • Если у вас мало процессов, вы можете открыть две трубы для двух направлений (processA2ProcessB и processB2ProcessA)
  • Если у вас много процессов, вы можете открывать и удалять каналы для каждого процесса (processAin, processAout, processBin, processBout, processCin, processCout и т.д.)
  • Или вы можете идти гибридом, как всегда:)

Именованные трубы довольно просты в реализации.

например. Я реализовал проект на C с именованными каналами, благодаря стандартной связи на основе ввода-вывода (fopen, fprintf, fscanf...) он был таким простым и чистым (если это тоже необходимо).

Я даже закодировал их с помощью java (я сериализовал и отправлял объекты над ними!)

Именованные трубы имеют один недостаток:

  • они не масштабируются на нескольких компьютерах, таких как сокеты, поскольку они полагаются на файловую систему (при условии, что разделяемая файловая система не является вариантом)

Ответ 7

Одна проблема с сокетами заключается в том, что у них нет способа сбросить буфер. Существует нечто, называемое алгоритмом Нагле, который собирает все данные и сбрасывает его через 40 мс. Так что если это отзывчивость и не пропускная способность, вам может быть лучше с трубой.

Вы можете отключить Nagle с опцией сокета TCP_NODELAY, но тогда конец чтения никогда не получит два коротких сообщения в одном вызове чтения.

Итак, протестируйте его, я не получил ни одного из этого и не реализовал запланированные очереди на основе памяти с mutex и семафором pthread в общей памяти, избегая множества системных вызовов ядра (но сегодня они не очень медленны).

Ответ 8

Именованные трубы и сокеты не являются функционально эквивалентными; сокеты предоставляют больше возможностей (они являются двунаправленными, для начала).

Мы не можем сказать вам, что будет работать лучше, но я сильно подозреваю, что это не имеет значения.

Сокеты домена Unix будут делать почти то, что будут сокеты tcp, но только на локальной машине и с (возможно, немного) более низкими служебными данными.

Если сокет Unix не достаточно быстрый, и вы переносите много данных, подумайте об использовании разделяемой памяти между вашим клиентом и сервером (что намного сложнее настроить).

Unix и NT имеют "Именованные каналы", но они совершенно разные в наборе функций.

Ответ 9

Вы можете использовать легкое решение, такое как ZeroMQ [zmq/0mq]. Он очень прост в использовании и значительно быстрее, чем сокеты.

Ответ 10

Лучшие результаты, которые вы получите с решением общей памяти.

Именованные каналы только на 16% лучше, чем TCP-сокеты.

Результаты получены с помощью сравнительного анализа IPC:

  • Система: Linux (Linux Ubuntu 4.4.0 x86_64 i7-6700K 4,00 ГГц)
  • Сообщение: 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