Работа в сети - моя худшая область в операционных системах, так что простите меня за, возможно, неполный вопрос.Я читал об этом в течение нескольких часов, но это как бы плавает в моей голове.(Мне кажется, что дизайн чипа проще, чем вычисление сетевых протоколов.)
У меня есть несколько сетевых сервисов, которые взаимодействуют друг с другом через сокеты.В частности, сокеты создаются с 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.Я предполагаю, что время ядра - это комбинация времени простоя и копирования данных, а не многое другое.
Заранее спасибо за помощь!