Разъемы для Linux: локальная нулевая копия, удаленный TCP / IP - PullRequest
4 голосов
/ 29 декабря 2011

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

У меня есть несколько сетевых сервисов, которые взаимодействуют друг с другом через сокеты.В частности, сокеты создаются с fd = socket(PF_INET, SOCK_STREAM, 0);, который автоматически получает TCP / IP.Мне это нужно в качестве базового варианта, потому что эти сервисы могут работать на разных машинах.

Но для одного проекта мы пытаемся втиснуть их всех во встроенное «устройство» с недостаточной мощностью, основанное на Atom.Z530P, поэтому мне кажется, что мы можем оптимизировать накладные расходы на копирование памяти.Я читал об этом здесь: data-link-access-and-zero-copy и Linux_packet_mmap и packet_mmap .

Дляв этом случае можно создать сокет примерно так: fd = socket(PF_PACKET, PF_RAW, 0);.И есть еще куча других вещей, таких как выделение кольцевых буферов, сопоставление их, связывание их с сокетом и т. Д. Похоже, вы ограничены использованием sendto и recvfrom для передачи данных.Насколько я понимаю, поскольку сокет является локальным, вам не нужен надежный сокет типа «поток», поэтому необработанный сокет является подходящим интерфейсом, и я предполагаю , что кольцевой буфер используется придетализация страницы, где каждый пакет (или датаграмма) начинается на границе страницы.

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

  • Какой выигрыш в производительности я должен ожидать от сокетов без копирования?Я думаю, что в последний раз, когда я проверял, мы перемещали максимум примерно 40 МБ / с из одного процесса в другой и, наконец, на диск.В самом основном сценарии данные перемещаются из процесса захвата в процесс «один ко многим» (другие могут прослушивать поток) в процесс архивирования, который записывает на диск.Это два прыжка, не считая диска и внутреннего содержимого.
  • Делает ли Linux все это автоматически, оптимизируя процессы, запущенные на той же машине?
  • В любом случае, я бы прослушивал сокеты вПорты TCP.Могу ли я использовать их для установления связей между процессами, но при этом иметь возможность использовать нулевое копирование?Другими словами, могу ли я использовать AF_INET с PF_PACKET?
  • Является ли PF_PACKET с SOCK_RAW единственной допустимой конфигурацией для сокетов с нулевым копированием?
  • Есть ли хороший пример кода, который будет использовать ноль-копировать с помощью TCP / IP в качестве запасного варианта?
  • Какой самый простой или лучший способ обнаружить, что два процесса находятся на одной машине?Они знают IP-адреса друг друга, поэтому я мог бы просто сравнить и использовать разные пути кода для каждого.Есть ли более простой способ сделать это?
  • Могу ли я использовать write () и read () для сокета на основе пакетов, или они действительны только для потоков?(Переписать способ создания соединений было бы проще, чем переписать ВСЕ код сокета.)
  • Я слишком усложняю вещи и / или оптимизирую не те вещи?OProfiler говорит мне, что большая часть процессорного времени расходуется в двух местах: (1) zlib и (2) ядро, которое я не могу профилировать, так как я использую CentOS 6.2, который не предоставляет vmlinux.Я предполагаю, что время ядра - это комбинация времени простоя и копирования данных, а не многое другое.

Заранее спасибо за помощь!

Ответы [ 2 ]

7 голосов
/ 29 декабря 2011

Я слишком усложняю вещи и / или оптимизирую не те вещи?

Возможно.Использование PF_PACKET сокетов только для специализированных вещей.Вы, вероятно, хотите посмотреть

Какой самый простой или лучший способ обнаружить, что два процесса находятся на одном компьютере?

Просто не «забыть» эту информацию.

Делает ли Linuxчто-нибудь из этого автоматически, оптимизируя процессы, запущенные на одной машине?

Нет, вы должны сделать это самостоятельно.

2 голосов
/ 01 января 2012

Я думаю, что выбор между TCP / IP и необработанными пакетами гораздо важнее, чем вопрос отсутствия копирования. Если вам нужна надежная потоковая связь, вам нужен TCP / IP (то есть AF_INET + PF_STREAM). Попытка реализовать надежный поток поверх ненадежных пакетов очень сложна, и это уже сделано для вас.

Лучший способ использовать TCP / IP с нулевым копированием и файлами - это, как говорит @cnicutar, sendfile (2) и splice (2). Я думаю, что есть способ наслаждаться нулевым копированием без них (если вы хотите читать данные в память, а не напрямую в файл), но я не уверен, как это сделать.

Кроме того, Centos является открытым исходным кодом, поэтому вы можете получить файл vmlinux, загрузив исходный код и скомпилировав его.

...