Si bien DMA alivia la CPU y, por lo tanto, puede reducir la latencia de otras aplicaciones controladas por interrupciones que se ejecutan en el mismo núcleo, existen costos asociados:
-
Solo hay una cantidad limitada de canales DMA y existen limitaciones sobre cómo estos canales pueden interactuar con los diferentes periféricos. Otro periférico en el mismo canal puede ser más adecuado para el uso de DMA.
Por ejemplo, si tiene una transferencia masiva de I2C cada 5 ms, esto parece ser un mejor candidato para DMA que un comando de depuración ocasional que llega a UART2.
-
Configurar y mantener DMA es un costo por sí solo. (Normalmente, la configuración de DMA se considera más compleja que la configuración de la transferencia normal basada en interrupciones por carácter, debido a la administración de la memoria, a la mayoría de los periféricos involucrados, a la DMA que utiliza interrupciones y la posibilidad de que necesite analizar los primeros caracteres fuera de DMA). De todos modos, ver más abajo.)
-
DMA puede usar potencia adicional , ya que es otro dominio del núcleo que necesita ser cronometrado. Por otro lado, puede suspender la CPU mientras la transferencia DMA está en curso, si el núcleo lo admite.
-
DMA requiere búferes de memoria para trabajar (a menos que esté haciendo DMA de periférico a periférico), por lo que hay un costo de memoria asociado.
(El costo de la memoria puede también está presente cuando se usan interrupciones por carácter, pero también puede ser mucho menor o desaparecer si los mensajes se interpretan de inmediato dentro de la interrupción).
-
DMA produce una latencia porque la CPU solo recibe una notificación cuando la transferencia está completa / la mitad está completa (consulte las otras respuestas).
-
Excepto cuando se transmiten datos a / desde un búfer de anillo, necesita saber de antemano cuántos datos recibirá / enviará.
-
Esto puede significar que es necesario procesar los primeros caracteres de un mensaje utilizando interrupciones por carácter: por ejemplo, al interactuar con un XBee, primero debe leer el tipo y tamaño de paquete y luego activar una transferencia DMA en un búfer asignado.
-
Para otros protocolos, esto puede no ser posible si solo usan delimitadores de fin de mensaje: por ejemplo, protocolos basados en texto que usan '\n'
como delimitador. (A menos que el periférico DMA admita la coincidencia en un personaje).
Como puede ver, hay muchas compensaciones que considerar aquí. Algunos están relacionados con las limitaciones de hardware (cantidad de canales, conflictos con otros periféricos, coincidencia con los caracteres), otros se basan en el protocolo utilizado (delimitadores, longitud conocida, búferes de memoria).
Para agregar algunas pruebas anecdóticas, me he enfrentado a todas estas concesiones en un proyecto de hobby que usaba muchos periféricos diferentes con protocolos muy diferentes. Hubo algunas concesiones que hacer, en su mayoría basadas en la pregunta "¿Cuántos datos estoy transfiriendo y con qué frecuencia voy a hacer eso?". Básicamente, esto le proporciona una estimación aproximada del impacto de la simple transferencia controlada por interrupciones en la CPU. Por lo tanto, le di prioridad a la transferencia I2C antes mencionada cada 5 ms sobre la transferencia UART cada pocos segundos que utilizaron el mismo canal DMA. Otra transferencia de UART que ocurre con más frecuencia y con más datos, por otro lado, tiene prioridad sobre otra transferencia I2C, lo que ocurre con menos frecuencia. Es todas las compensaciones.
Por supuesto, usar DMA también tiene ventajas, pero eso no es lo que pediste.