Нулевое копирование с и без операций Scatter / Gather - PullRequest
6 голосов
/ 19 марта 2012

Я только что прочитал статью , которая объясняет механизм нулевого копирования.

В нем говорится о разнице между нулевым копированием с поддержкой Scatter / Gather и без нее.

NIC без поддержки SG , копии данных:

enter image description here

NIC с поддержкой SG , копии данных следующие

enter image description here

Одним словом, нулевое копирование с поддержкой SG может устранить одну копию процессора.

Мой вопрос заключается в том, что почему данные в буфере ядра могутбыть рассеянным ?

Ответы [ 3 ]

14 голосов
/ 19 марта 2012

Поскольку средства отображения / выделения памяти ядра Linux по умолчанию будут создавать практически непрерывные, но, возможно, физически не связанные области памяти.
Это означает, что чтение из файловой системы, которое sendfile() внутренне отправляет в буфер в виртуальная память ядра , которую код DMA должен «преобразовать» (из-за отсутствия лучшего слова) в нечто, что может обработать механизм DMA сетевой карты.

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

Если ваш механизм DMA, с другой стороны, способен объединять несколько физически непересекающихся областей памяти в одну передачу данных (это называется "scatter-collect ") тогда вместо копирования буфера вы можете просто передать список физических адресов (указывая нафизически допустимые подсегменты буфера ядра, это ваши агрегатные дескрипторы выше), и вам больше не нужно начинать отдельную передачу DMA для каждой физической страницы.Обычно это быстрее, но может ли это быть сделано или нет, зависит от возможностей механизма прямого доступа к памяти.

4 голосов
/ 19 марта 2012

Re: Мой вопрос таков: почему данные в буфере ядра могут быть разбросаны?

Поскольку они уже разбросаны.Очередь данных перед сокетом TCP не разделяется на дейтаграммы, которые выходят на сетевой интерфейс.Scatter позволяет хранить данные там, где они есть, и не нужно копировать их для создания плоского буфера, приемлемого для оборудования.

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

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

2 голосов
/ 20 марта 2012

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

Кроме того, чтобы избежать необходимости считывания данных процессором (и, следовательно, заполнения его кеша ненужными данными, которые больше никогда не понадобятся), сетевой карте также необходимо генерировать свои собственные контрольные суммы IP и TCP (я предполагаю, TCP здесь, потому что 99% ваших массовых передач данных будет TCP). Это нормально, потому что в настоящее время они все могут.

Что я не уверен, так это то, как все это взаимодействует с TCP_CORK.

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

Клиент: Отправить запрос Сервер: отправьте несколько метаданных; отправить данные файла

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

...