2012-05-17 17 views
18

Actualmente, estoy tratando de comprender el valor de splice/vmsplice. En cuanto al caso de uso de la CIP, me topé con la siguiente respuesta en stackoverflow: https://stackoverflow.com/a/1350550/1305501Linux Zero-Copy: transferir páginas de memoria entre dos procesos con vmsplice

Pregunta: ¿Cómo transferir páginas de memoria de un proceso a otro proceso utilizando vmsplice sin copiar los datos (es decir, copia cero)?

La respuesta mencionada anteriormente afirma que es posible. Sin embargo, no contiene ningún código fuente. Si entiendo correctamente la documentación de vmsplice, la siguiente función transferirá las páginas de memoria a una tubería (memoria intermedia del kernel) sin copiar, si la memoria está asignada y alineada correctamente. Se omite el manejo de errores por la facilidad de presentación.

// 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); 
    } 
} 

Pero, ¿cómo se puede acceder a las páginas de memoria desde el espacio de usuario sin copiar? Aparentemente, los siguientes métodos no funcionan:

  • vmsplice: Esta función también se puede utilizar en sentido inverso. Pero según los comentarios en el kernel sources, los datos serán copiados.
  • read: Me imagino que esta función produce algo de magia si la memoria está alineada correctamente, pero lo dudo.
  • mmap: No es posible en la tubería. Pero, ¿hay algún tipo de archivo virtual que se pueda usar en su lugar, es decir, splice las páginas de memoria en el archivo virtual y mmap?
  • ...?

¿No es posible en absoluto con vmsplice?

+4

No creo que sea una buena idea crear una función no estática llamada "send()". – wildplasser

+1

De hecho, eso está invocando un comportamiento indefinido en POSIX. –

+0

No creo que su llamada a 'vmsplice' en' recibir' tenga sentido. Es una llamada para escribir, no para leer ... –

Respuesta

6

Como se mencionó en R .., solo necesita pasar el fd al proceso de recepción somehow y en el otro lado usarlo como un fd normal.

edición: En realidad, usted tiene que utilizar vmsplice() en el lado de envío para asignar la memoria intermedia de la tubería y el empalme() en el lado receptor en el otro extremo de la tubería. Vea un ejemplo here.

Otra opción sería usar un mmap-ing compartido.

+3

Supongamos que el otro proceso ya tiene un fd en el otro extremo de la tubería. La pregunta es: ¿puede mapear las páginas de memoria en su espacio de direcciones sin copiar los datos? Dudo que 'read (2)' contenga tal optimización, ¿o sí? – nosid

+0

El kernel debe manejar esta asignación de página. Además, mira mi edición. – dtatulea

Cuestiones relacionadas