Actualmente estoy agregando DMA a mi controlador PCIe para Linux. Mientras leo la documentación, menciona la memoria consistente o coherente mediante el uso de la API:
pci_set_consistent_dma_mask(...)pero nunca habla realmente sobre por qué usarlo o qué hace. Parece mencionar llamar a la función para mejores prácticas y pruebas futuras. Lo mejor que puedo deducir es que la memoria DMA consistente no tiene efectos de caché y la memoria se escribe entre el dispositivo (FPGA) y la CPU sin ninguna intervención de software/controlador una vez configurada correctamente (suponiendo que leo correctamente). Entonces mis preguntas son:
Piénselo de esta manera: "Consistente" significa que será automáticamente coherente entre la CPU y el bus sin hacer nada para sincronizarlo específicamente . Por ejemplo, supongamos que tengo un anillo de memoria para paquetes entrantes y salientes. Su vida útil será todo el tiempo que el sistema esté en uso, y voy a estar revisándolo todo el tiempo. Quiero que esto sea siempre consistente, porque si no lo es, tendría que vaciar o sincronizar (manualmente) los cachés, y si esto fuera costoso, y tuviera que hacerlo justo cuando toqué el anillo, sería una pesadilla. .
Por otro lado, tomemos un solo búfer de datos que estoy transfiriendo. No soy una especie de trato "único". Puedo dejar que el dispositivo lo transfiera, y tal vez se necesiten muchos ciclos de PCI para completar el DMA. Y tal vez esto es inconsistente . Está bien, pero cuando termine , puedo vaciar/sincronizar cachés/forzar la consistencia. Si me tomó un poco de tiempo extra hacerlo, no hay problema, porque solo lo estoy haciendo una vez .
Por lo tanto, podría preguntarse "¿por qué no hacer que todo sea coherente?". La respuesta es que generalmente hay algún nivel de gastos generales para que las cosas sean consistentes. Dependiendo de la arquitectura, esto podría ser significativo. Entonces, en tales casos, existen disposiciones para permitir asignaciones inconsistentes (transmisión) que no tienen coherencia de caché (pero requieren una sincronización explícita ). Por lo tanto, permitir una transferencia inconsistente podría mejorar su rendimiento.
Recuerde también: hay algunos casos en los que nunca necesitaría consistencia. Por ejemplo, leer un búfer de un dispositivo de red en la memoria y luego escribir esa memoria en un controlador de disco. Es posible que la CPU nunca lea/utilice estos datos, entonces, ¿por qué molestarse en colocar una sobrecarga en el caché de la CPU para rastrearlos?
En cuanto a tu comentario sobre la "interrupción", esto es un poco extraño. En un caso "normal", es posible que tenga una estructura de control en la memoria consistente (como anillos Tx/Rx) que podría sondear para indicarle si se realizó la transacción. Pero los datos reales transferidos estarían en una memoria diferente que podría transmitirse o no ser consistente.
1) Imagine que desea transferir una gran cantidad de datos a través de PCIE, con una tasa alta. tiene que usar una lista de dispersión/recopilación, y puede usar una memoria consistente para preparar esta lista para FPGA, por lo que FPGA puede leer esta lista muy rápido y luego hacer las transmisiones.
2) Por supuesto que necesita interrupciones, de lo contrario, debe usar el sondeo, que es muy lento y poco confiable.
3) Si usa una memoria consistente más grande, puede minimizar los gastos generales de interrupción / sondeo, por lo que son más rápidos, pero las ventanas generalmente no le permiten asignar una memoria consistente grande.