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

114

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

user19745
источник
10
Ваш пробег будет отличаться. :) Профилируйте типичное использование для вашего предполагаемого приложения и выберите лучшее из двух. Затем профилируйте анонимные каналы, сокеты других доменов и семейств, семафоры и разделяемую память или очереди сообщений (SysV и POSIX), сигналы реального времени со словом данных или что-то еще. pipe(2)mkfifo(3)?) может быть победителем, но вы не узнаете, пока не попробуете.
pilcrow
2
Очереди сообщений SysV FTW! Понятия не имею, быстрые ли они, просто у меня к ним слабость.
Том Андерсон
4
Что в этом случае «скорость»? Общая скорость передачи данных? Или задержка (как быстро первый байт попадает в приемник)? Если вам нужна быстрая локальная передача данных, то трудно превзойти общую память. Однако, если задержка является проблемой, тогда вопрос становится более интересным ...
Ян Ни-Льюис,

Ответы:

64

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

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

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

Shodanex
источник
48

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

Именованные каналы всего на 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
chronoxor
источник
1
Спасибо за подробный сравнительный анализ. Вы имеете в виду "multiprocessing.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.

Yuliy
источник
1
А как насчет Windows?
Pacerier
1
@Pacerier К сожалению, вы не можете создавать локальные сокеты в Windows так же, как абстрактное пространство имен в UNIX. Я обнаружил, что сокеты PF_UNIX работают значительно быстрее (> 10%), чем большинство других методов, описанных на этой странице.
EntangledLoops
1
devblogs.microsoft.com/commandline/af_unix-comes-to-windows update, сокеты Unix теперь доступны в Windows 10.
eri0o
27

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

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

Hibou57
источник
11

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

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

Дэмиен
источник
8

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

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

Именованные каналы довольно легко реализовать.

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

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

Именованные каналы имеют один недостаток:

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

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

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

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

Лотар
источник
3
«Так проверь это» <- слова, по которым нужно жить.
Koshinae
6

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

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

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

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

В Unix и NT есть «именованные каналы», но они полностью различаются по набору функций.

MarkR
источник
1
Что ж, если вы откроете 2 трубы, вы также получите поведение биди.
Pacerier
4

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

Амит Вуич
источник
2
Возможно, вам понравится, угадайте, Амит, следующая работа Мартина СУСТРИКА - совместимая с POSIX nanomsg. В любом случае, добро пожаловать и наслаждайтесь этим прекрасным местом и станьте его активным участником.
user3666197 02