Linux Zero-Copy: передача страниц памяти между двумя процессами с помощью vmsplice

В настоящее время я пытаюсь понять значение splice/vmsplice. Что касается варианта использования IPC, я наткнулся на следующий ответ в stackoverflow: https://stackoverflow.com/a/1350550/1305501< /а>

Вопрос: Как перенести страницы памяти из одного процесса в другой с помощью vmsplice без копирования данных (т. е. с нулевым копированием)?

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

// data is aligned to page boundaries,
// and length is a multiple of the page size
void transfer_to_pipe(int pipe_out, char* data, size_t length)
{
    size_t offset = 0;
    while (offset < length) {
        struct iovec iov { data + offset, length - offset };
        offset += vmsplice(pipe_out, &iov, 1, SPLICE_F_GIFT);
    }
}

Но как можно получить доступ к страницам памяти из пользовательского пространства без копирования? По-видимому, следующие методы не работают:

Разве это вообще невозможно с vmsplice?


person nosid    schedule 17.05.2012    source источник
comment
Я не думаю, что это хорошая идея — создавать нестатическую функцию с именем send().   -  person wildplasser    schedule 17.05.2012
comment
Действительно, это вызывает неопределенное поведение в POSIX.   -  person R.. GitHub STOP HELPING ICE    schedule 17.05.2012
comment
Я не думаю, что ваш звонок vmsplice в receive имеет смысл. Это призыв писать, а не читать...   -  person R.. GitHub STOP HELPING ICE    schedule 17.05.2012
comment
Хотя это не упоминается на справочной странице моей системы, vmsplice, по-видимому, поддерживает оба направления. Однако, как я указал, обратное направление не является нулевым копированием. См. источник vmsplice.   -  person nosid    schedule 17.05.2012


Ответы (1)


Как упоминал Р.., вам нужно только передать fd принимающему процессу high-volume-data-between-2-process/1350550#1350550">каким-то образом, а с другой стороны использовать его как обычный fd.

редактировать: На самом деле вам нужно использовать vmsplice() на стороне отправки, чтобы сопоставить буфер с каналом, и splice() на принимающей стороне на другом конце канала. См. пример здесь.

Другим вариантом было бы использование общего mmap-ing.

person dtatulea    schedule 17.05.2012
comment
Предположим, что у другого процесса уже есть fd на другом конце канала. Вопрос в том, может ли он отображать страницы памяти в свое адресное пространство без копирования данных? Я сомневаюсь, что read(2) содержит такую ​​оптимизацию, не так ли? - person nosid; 17.05.2012