Каковы пределы использования сокетов для межпроцессного взаимодействия?

Я создаю расширение для Firefox, которое позволяет использовать Standard ML (SML) в качестве клиентского языка программирования в Firefox. Это работает следующим образом:

  1. Расширение запускает процесс PolyML (компилятор SML с интерактивной оболочкой верхнего уровня).
  2. Затем устанавливается связь через сокет между расширением и процессом PolyML.
  3. Код SML считывается с веб-страницы и отправляется через сокеты в процесс PolyML для оценки.
  4. Затем этот код может использовать предоставленную мной библиотеку для работы с DOM.

Вот как реализована библиотека DOM:

  1. Скажем, кто-то выполняет функцию SML DOM.getElementById
  2. Этот запрос перенаправляется через сокеты в расширение, где расширение выполняет функцию JavaScript getElementById на странице и отправляет результат обратно в процесс PolyML через сокеты.

Мой вопрос заключается в том, теоретически, какие ограничения с точки зрения производительности я должен ожидать здесь, когда дело доходит до связи через сокет?

Я сделал очень приблизительное профилирование, и кажется, что, используя этот интерфейс между расширением и PolyML, я могу отправить приблизительно 2500 сообщений в секунду со средним размером 70 байт/сообщение.

Чтобы поместить это в больший контекст, предположим, что я хочу нарисовать анимацию в браузере, используя элемент Canvas. Если я хочу получить 20 кадров в секунду, это означает, что мне нужно отрисовывать каждый кадр за 0,05 секунды, что означает, что я могу отправить только около 125 сообщений за кадр. Эти сообщения соответствуют вызовам функций JavaScript. Например, приведенный ниже код рисует путь и выполняет 9 вызовов функций JavaScript, которые соответствуют 9 сообщениям в сокетной связи.

val _ = Canvas.beginPath context;
val _ = Canvas.setFillStyle context fillColor;
val _ = Canvas.setStrokeStyle context fillColor;
val _ = Canvas.setLineWidth context size;
val _ = Canvas.moveTo context posx posy;
val _ = Canvas.lineTo context posx_new posy_new;
val _ = Canvas.stroke context;
val _ = Canvas.arc context posx_new posy_new (size/2.0) 0.0 6.28 true;
val _ = Canvas.fill context;

JavaScript, очевидно, имеет гораздо лучшую производительность, я полагаю, что вы могли бы сделать тысячи (сотни) вызовов функций Canvas/DOM за эти 0,05 секунды для рисования кадра.

Итак, я думаю, мой вопрос в том, есть ли у вас опыт использования связи через сокеты для очень быстрого обмена сообщениями. Я хотел бы знать, кажется ли правильным 2500 небольших сообщений в секунду (в данном случае, что соответствует 150 кбайтам в секунду) или я делаю что-то очень неправильно.

Например, есть подозрение, что реализация сокета в firefox (в частности, его использование через интерфейс JavaScript https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIServerSocket) не очень подходит для такого быстрого взаимодействия. Например, чтение из сокета выполняется с помощью механизма цикла обработки событий. То есть я полагаюсь на Firefox... чтобы уведомить меня о доступности входящих сообщений сокета, и иногда между отправкой сообщения и его получением возникает большая (например, 250 мс) задержка (хотя, похоже, это происходит только тогда, когда Firefox занят выполнением другие вещи, и меня больше интересуют .. теоретические .. пределы связи через сокет)

Какие-нибудь идеи, какие-нибудь мысли, какие-нибудь недостатки, которые вы видите? Как вы думаете, было бы лучше использовать другие механизмы IPC, например. каналы, реализующие мою коммуникацию из компонента C++ XPCOM, а не из JavaScript, интерфейса внешней функции для C (который есть как в JavaScript, так и в PolyML)?

(Проект находится по адресу https://assembla.com/wiki/show/polymlext, если кто-то интересно)


person Karolis    schedule 26.11.2010    source источник
comment
Вы используете TCP? UDP? или сокеты UNIX? Последнее должно быть быстрее, поскольку ОС не должна заботиться о сетевых ошибках.   -  person bew    schedule 22.02.2012
comment
не уверен, я использовал developer.mozilla.org/en/XPCOM_Interface_Reference/. Вы знаете, это TCP, UNIX или настраиваемый?   -  person Karolis    schedule 22.02.2012
comment
Я также понял, что узким местом может быть кодирование/декодирование JSON, хотя я уже не помню, сколько этого там использовалось.   -  person Karolis    schedule 22.02.2012
comment
Если я правильно понимаю источник, nsIServerSocket всегда использует AF_INET, даже для локальных подключений. scottmoonen.com/tag/af_inet дает сравнение между ними: 100 ГБ переданы за 80,575200 с для AF_UNIX. , 100 ГБ передано за 226,717520 с для AF_INET+loopback.   -  person bew    schedule 24.02.2012
comment
IHMO, TCP будет достаточно быстрым и будет работать кроссплатформенно. Нет сокетов UNIX в Windows AFAIK. Вашей самой большой проблемой будет сериализация данных.   -  person James Mills    schedule 31.10.2012


Ответы (1)


TCP можно настроить на более высокую пропускную способность или более быстрое время отклика. Для более высокой пропускной способности вам необходимо установить большее значение для буфера сокета. Чтобы получить хорошее время отклика с меньшим объемом данных, вам необходимо установить параметр сокета TCP_NODELAY. TCP на петле, если он точно настроен, он должен быть идентичен любому механизму IPC. Более новая ОС Windows выполняет специальную оптимизацию, такую ​​как увеличение размера MTU и т. Д., На адаптере обратной связи, чтобы сделать его быстрее.

person dvasanth    schedule 07.06.2014