¿Los comedores de pollo comen memoria o CPU?
Conociendo la ruta completa, comencé a estudiar cómo era el hardware en cada paso y cómo pasaban las instrucciones de lectura y escritura a través de él. Para entender el hardware, primero debemos hablar del procesador. La estructura básica del procesador no es complicada y generalmente se divide en cinco pasos: búsqueda de instrucciones, decodificación, transmisión, ejecución y reescritura. Cuando hablamos de acceder a la memoria, nos referimos a acceder a datos, no a buscar instrucciones. En los primeros tres pasos, no hay nada especial en las instrucciones para acceder a los datos. En el cuarto paso, se enviará a la unidad de acceso para esperar su finalización. Algunos problemas interesantes surgen cuando las instrucciones están en la unidad de acceso.
La primera pregunta es, cuando el procesador está esperando que se devuelvan datos del caché o la memoria, ¿cuál es el estado de la instrucción de lectura? ¿Deberíamos esperar allí o seguir otras instrucciones?
En términos generales, si se trata de un procesador que se ejecuta fuera de servicio, se pueden ejecutar las siguientes instrucciones. Si se ejecuta secuencialmente, entrará en un estado de pausa hasta que regresen los datos leídos. Por supuesto, esto no es absoluto. Antes de dar un contraejemplo, primero debemos entender qué es la ejecución desordenada. La ejecución fuera de orden significa que para una serie determinada de instrucciones, para mejorar la eficiencia, el procesador encontrará instrucciones que realmente no dependen de datos y las dejará ejecutar en paralelo. Sin embargo, cuando los resultados de la ejecución de instrucciones se escriben en registros, deben ser secuenciales. Es decir, incluso si la instrucción se ejecuta primero, el resultado de la operación se volverá a escribir en el registro final en el orden de las instrucciones. Esto es diferente de la ejecución desordenada que muchos programadores entienden. Descubrí que algunas personas piensan que al depurar problemas de software, el uso de un procesador fuera de servicio puede hacer que el código posterior se ejecute primero, lo que imposibilita la depuración.
Confunden dos conceptos, a saber, el orden de acceso a la memoria y el orden de finalización de las instrucciones. Para las instrucciones de operación ordinarias, solo se ejecutan dentro del procesador, por lo que lo que ve es la orden de reescritura. Para las instrucciones de acceso, la instrucción genera una solicitud de lectura y la envía fuera del procesador. El orden que ve es el orden de acceso. Para los procesadores desordenados, puede haber múltiples solicitudes al mismo tiempo y su orden está desordenado. Pero en este momento, estas solicitudes de lectura enviadas al exterior no obtuvieron resultados y las instrucciones no se completaron. Por lo tanto, esto no viola el principio de ejecución desordenada y finalización secuencial. Si hay dos instrucciones de lectura antes y después, y no hay asociación de datos, incluso si los datos leídos en la última se devuelven primero, el resultado no se puede volver a escribir primero en el registro final, sino que se debe esperar hasta el anterior. está completo.
Para los procesadores que se ejecutan secuencialmente, también hay dos instrucciones de lectura. Generalmente, la segunda instrucción no se puede ejecutar hasta que se complete la primera instrucción, por lo que lo que se ve fuera del procesador es un acceso secuencial. Sin embargo, hay excepciones. Por ejemplo, cuando la lectura y la escritura existen al mismo tiempo, debido a que las instrucciones de lectura y escritura en realidad toman dos caminos, puede parecer que existen al mismo tiempo.
Además, incluso si hay dos instrucciones de lectura en un procesador secuencial, puede haber dos solicitudes externas al mismo tiempo. Por ejemplo, Cortex-A7, para instrucciones de lectura continua, cuando la operación de lectura anterior no alcanza el caché de primer nivel, se puede ejecutar la segunda instrucción de lectura y los datos se pueden recuperar del caché o memoria del siguiente nivel. Por tanto, el desorden y el orden no afectan directamente al orden de ejecución de las instrucciones. La diferencia entre los dos es que el proceso fuera de orden requiere búferes y bloques lógicos adicionales (llamados búferes de reordenamiento) para calcular y almacenar las dependencias entre las instrucciones y el estado de ejecución, mientras que los procesadores secuenciales no tienen búferes de reordenamiento o son muy simples. Esta área adicional no es pequeña, hasta donde puedo ver, puede representar 40 de los núcleos del procesador. Aportan un mayor grado de paralelismo, pero la mejora del rendimiento puede no ser del 40%. Debido a que estamos escribiendo un programa de un solo subproceso, debido a que hay muchas dependencias de datos y el paralelismo de las instrucciones es limitado, no importa cuán grande sea el búfer de reordenamiento, no puede resolver las dependencias de datos reales.
Por lo tanto, los procesadores sensibles a la energía todavía utilizan la ejecución secuencial.
También cabe señalar que durante las fases de búsqueda, decodificación y transferencia de instrucciones de un procesador que se ejecuta secuencialmente, se pueden ejecutar dos o más instrucciones simultáneamente. Por ejemplo, las instrucciones de lectura e instrucciones de operación independientes se pueden enviar a diferentes unidades de ejecución al mismo tiempo e iniciar la ejecución al mismo tiempo. Pero la finalización aún está en proceso.
Sin embargo, en algunos procesadores ARM, como Cortex-A53, las instrucciones vectoriales o de cifrado y descifrado se pueden completar desordenadamente y no existe dependencia de datos entre los resultados de dichas operaciones. Por favor tenga en cuenta esto.
Veamos las instrucciones de escritura. Existe una gran diferencia entre escribir y leer, es decir, la instrucción de escritura se puede completar sin esperar a que los datos se escriban en el caché o la memoria. Los datos escritos van a un búfer llamado búfer de almacenamiento, que se encuentra antes del caché L1. Mientras no esté lleno, el procesador puede apagarse directamente sin detenerse ni esperar. Por lo tanto, para instrucciones de escritura consecutivas, independientemente de si el procesador las ejecuta en secuencia o fuera de orden, es posible ver múltiples solicitudes de escritura colgadas en el bus del procesador al mismo tiempo. Al mismo tiempo, dado que el procesador puede enviar más solicitudes de escritura por unidad de tiempo sin esperar el resultado como una instrucción de lectura, podemos ver que el ancho de banda de escritura suele ser mayor que el ancho de banda de lectura.
El acceso de lectura y escritura anterior es cuando el caché está activado.
Para múltiples solicitudes que existen al mismo tiempo, existe un sustantivo para definirlas, llamado transacción pendiente, u OT para abreviar. Junto con la latencia, forma nuestra descripción del rendimiento del acceso a la memoria. El concepto de retraso tiene diferentes definiciones en distintos ámbitos. En la red, la latencia de la red se refiere al tiempo total que tarda un solo paquete de datos en iniciarse localmente, pasar por la conmutación y el enrutamiento, llegar al extremo opuesto y luego regresar. En un procesador, también podemos decir que la latencia de lectura y escritura es el tiempo que tarda en emitirse una instrucción, pasar por la caché, el bus, el controlador de memoria, las partículas de memoria y luego regresar a la ruta original. Sin embargo, la mayoría de las veces, la latencia de acceso de la que hablamos es el tiempo de acceso promedio después de que se ejecuta una gran cantidad de instrucciones de lectura y escritura. La diferencia aquí es que cuando OT=1, el retraso total simplemente se acumula. Cuando OT gt1, debido a que hay dos accesos paralelos, el tiempo total suele ser menor que el tiempo acumulado, o puede ser mucho menor. La latencia promedio obtenida en este punto, también conocida como latencia de acceso, es la que se utiliza más comúnmente. Para ser más precisos, debido a la existencia de canalizaciones de varias etapas, suponiendo que cada etapa de la canalización es un ciclo de reloj, la latencia promedio para acceder a la caché de primer nivel es en realidad un ciclo. Para la memoria caché L2, la caché L3 y la memoria, la latencia es el tiempo desde que se emite la instrucción (tenga en cuenta que no desde la recuperación de la instrucción) hasta la devolución de los datos finales, porque el procesador espera en la fase de ejecución y la canalización no está funcionando. Si OT=2, el tiempo puede reducirse casi a la mitad. Los beneficios de OT gt1 se reflejan aquí. Por supuesto, esto tiene un costo. Almacenar el estado de las solicitudes de lectura pendientes requiere buffers adicionales y es posible que el procesador también necesite admitir la ejecución fuera de orden, lo que resulta en mayores aumentos en el área y el consumo de energía. Para instrucciones de escritura, sigue siendo un ciclo de reloj siempre que el búfer de almacenamiento no esté lleno. Por supuesto, si un latido en la tubería dura más de un ciclo de reloj, la latencia promedio dependerá del tiempo más lento. Al leer los cachés y la memoria de segundo y tercer nivel, podemos considerar la espera de retorno como un latido y, naturalmente, podemos comprender el retraso en este momento. A partir de esto se puede obtener la latencia y la latencia de acceso de cada nivel de caché.
La imagen muestra la unidad por donde pasan las instrucciones de lectura y escritura. Permítanme describir el proceso brevemente:
Cuando una instrucción de escritura comienza desde la unidad de acceso LSU, primero pasa por una pequeña cola de almacenamiento y luego ingresa al búfer de almacenamiento. Posteriormente, la instrucción de escritura puede completarse y el procesador no tiene que esperar. El búfer de almacenamiento normalmente consta de varias ranuras de 8 a 16 bytes. Verificará la dirección de cada elemento de datos recibido, los fusionará si es posible y luego enviará una solicitud al caché de primer nivel a la derecha, asignando una línea de caché para almacenar los datos hasta que se reciba una respuesta. Esto se llama asignación de escritura. Por supuesto, el proceso de espera puede continuar fusionando los mismos datos de la línea de caché. Si los datos no se pueden almacenar en caché, calcula el tiempo de espera y luego fusiona los datos y los envía al búfer de escritura en la unidad de interfaz de bus BIU. Antes de enviar datos a la caché L2, el búfer de escritura pasa por la unidad de monitoreo para mantener consistentes las cachés en los cuatro núcleos.
El proceso es similar al descrito para el autobús, por lo que no entraré en detalles.
Cuando una instrucción de lectura comienza desde la unidad de acceso LSU, pasará a través del caché de primer nivel independientemente de si es almacenable en caché o no. Si se acierta, los datos se devuelven directamente y se completa la instrucción de lectura. Si falla, la solicitud que no se puede almacenar en caché se envía directamente al búfer de lectura. Si se puede almacenar en caché, el caché L1 necesita asignar una línea de caché, escribir los datos originales en el búfer de desalojo del búfer de reemplazo, iniciar un llenado de línea de caché y enviar al búfer de llenado de línea. El búfer de desalojo envía su solicitud de escritura al búfer de escritura de BIU y se envía a la siguiente interfaz junto con los datos enviados por el búfer de almacenamiento. Luego, estas solicitudes se envían a la caché L2 después de una verificación de coherencia por parte de la unidad de monitoreo. Por supuesto, es posible que los datos que se leen existan en la caché L1 de otro procesador, por lo que se obtienen directamente desde allí.
El proceso no es complicado, pero a los programadores les preocupa dónde está el cuello de botella de este proceso y cómo afecta el rendimiento de lectura y escritura. Ya hemos explicado que para las escrituras, dado que se puede completar inmediatamente, el cuello de botella no proviene de la unidad de acceso, para las lecturas, dado que el procesador esperará, necesitamos saber cuántos OT se pueden emitir en cada paso de la lectura; ruta, ¿cuál es la longitud de los datos de cada OT?
Tomemos Cortex-A7 como ejemplo. Tiene un búfer de llenado de línea de 2x32 bytes y admite fallas condicionales (las instrucciones de lectura adyacentes deben estar dentro de los 3 ciclos de reloj), es decir, OT es como máximo igual a 2, y su caché de datos La longitud de la línea es de 64 bytes, por lo que cada OT es la mitad de la longitud de la línea de caché. Para las lecturas almacenables en caché, también me preocupan dos datos, el búfer de desalojo y el búfer de escritura, que siempre van acompañados de rellenos de filas. En el A7, hay un búfer de desalojo de 64 bytes y un búfer de escritura. Con estas condiciones, entonces puedo decir que el OT de las instrucciones de lectura continua que puedo hacer es 2. La velocidad de relleno de línea es la misma que la de desalojo y búfer de escritura, porque 2x32=64 bytes.
¿Es correcta esta conclusión? Escribe un pequeño programa y pruébalo. Podemos desactivar el caché L2, conservar el caché L1 y luego usar las siguientes instrucciones para leer un área de memoria más grande. Todas las direcciones están alineadas con líneas de caché, por lo que no hablaré sobre el significado de alineación. La desalineación incluso cruza los límites de la línea de caché, convirtiendo una operación en dos, lo que seguramente será lento. El pseudocódigo es el siguiente:
loopload R0, addr 0load R0, addr 4load R0, addr 8load R0, addr 12 addr = addr 16
Aquí, lea continuamente los datos de la instrucción de lectura . A través del contador de rendimiento que viene con el procesador, podemos ver la tasa de fallos del caché del siguiente nivel, que es un poco más de 6. Ésta es exactamente la proporción de 4/64 bytes. Muestra que para una nueva línea de caché, los primeros cuatro bytes siempre son un error y los siguientes 15 bytes siempre son un éxito. Por supuesto, la latencia y el ancho de banda específicos también están relacionados con el bus y el controlador de memoria, y solo se pueden verificar simplemente utilizando la tasa de aciertos.
Para algunos procesadores, se ejecutan estrictamente en secuencia y no existe un mecanismo de fuga como A7, por lo que OT = 1. Hice el mismo experimento en Cortex-R5, que tiene una longitud de línea de caché de 32 bytes y un búfer 2xLinefill de 32 bytes. La tasa de aciertos de la prueba fue 12. También está completamente en línea con las estimaciones.
Pero ¿por qué R5 diseña dos buffers Linefill de 32 bytes? Dado que su OT=1, ¿no es inútil el extra? De hecho, se puede utilizar mediante la instrucción de captación previa PLD. La característica de las instrucciones de captación previa es que después de la ejecución, el procesador no tiene que esperar y la solicitud de lectura también se enviará al caché de primer nivel. La próxima vez que una instrucción de lectura lea la misma línea de caché, es posible que los datos ya estén allí. Su dirección debe estar alineada con la línea de caché. De esta manera, la lectura también puede llenar el búfer con la segunda línea, al igual que la escritura.
Usamos esto en el ejemplo anterior:
loopPLD addr 32load R0, addr 0; load R0, load R0, addr 32; cargar R0, dirección 60; dirección = dirección 64
PLD lee previamente la dirección de la instrucción de lectura en la segunda línea. La prueba encontró que la tasa de detección fallida en este momento todavía era 6. Esto también es consistente con la estimación, porque las instrucciones de lectura de la segunda fila siempre aciertan y la tasa de fallos de la primera fila es 4/32, con un promedio de 6. El ancho de banda de la prueba aumentó en más del 80%. Con solo mirar OT=2, debería ser un aumento de 100, pero no es tan ideal, y 80 es comprensible.
Otro mecanismo que hace que OT sea más grande es la captación previa de hardware en caché. Cuando un programa accede a una dirección continua o regular, el caché detectará automáticamente este patrón y recuperará los datos por adelantado. Este método también consume tiempo del procesador, pero también consume el búfer de llenado de línea, el búfer de desalojo y el búfer de escritura. Por lo tanto, si esta regla no se cumple adecuadamente, la eficiencia se verá reducida.
Después de leerlo, ¿qué tal si lo anotas? Si una escritura almacenable en caché no llega al caché, resultará en una asignación de escritura, lo que resultará en el llenado y desalojo de una fila, una operación de lectura. Es posible que muchos programadores no esperen esto. Cuando se escriben direcciones consecutivas, irá acompañada de una serie de operaciones de lectura de línea de caché. A veces, estas lecturas no significan nada. Por ejemplo, en la función memset, los datos se pueden escribir directamente en la memoria caché o memoria del siguiente nivel sin lectura adicional. Por tanto, la mayoría de los procesadores ARM implementan un mecanismo. Cuando se detecta una escritura en una dirección consecutiva, el búfer de almacenamiento no puede enviar los datos al caché L1, sino directamente al búfer de escritura. Además, en este momento es más fácil fusionarse para formar una escritura continua, lo que mejora la eficiencia. En Cortex-A7, se llama modo de asignación de lectura, lo que significa que las asignaciones de escritura se cancelan. En algunos procesadores se llama modo streaming. Muchas pruebas en ejecución activarán este modo, por lo que puede tener una ventaja en la ejecución de puntuaciones.
Sin embargo, entrar en modo streaming no significa que las direcciones recibidas por el controlador de memoria sean todas consecutivas. Imagine que cuando medimos memcpy, primero necesitamos leer los datos de la dirección de origen y enviarlos como una dirección continua. Esta dirección se basa en la línea de caché. Después de un tiempo, el caché se agota y luego se producen desalojos, que son aleatorios o pseudoaleatorios, y las direcciones escritas son irregulares. Esto interrumpe la lectura continua original de direcciones. Mirando de nuevo la escritura, al escribir datos en la dirección de destino, si se encuentran direcciones de escritura consecutivas, no se activará el llenado de filas adicionales ni el desalojo. Esto es algo bueno. Sin embargo, es posible que los datos escritos directamente en la memoria caché o memoria del siguiente nivel no se escriban en una ráfaga de caché completa porque el búfer de almacenamiento también interactúa constantemente con el búfer de escritura, y el búfer de escritura también acepta solicitudes de búfer de desalojo. El resultado es que la escritura se divide en pequeños párrafos. Las direcciones de escritura de estos pequeños bloques, las direcciones de escritura desalojadas y las direcciones de lectura se mezclan, lo que aumenta la carga sobre el bus y el controlador de memoria. Deben emplear algoritmos y parámetros apropiados para fusionar más rápidamente estos datos y escribirlos en partículas de almacenamiento.
Sin embargo, las cosas aún no han terminado. Como acabamos de mencionar, se activa el modo streaming y, de igual forma, también se puede salir del mismo. La condición de salida suele ser el descubrimiento de una ráfaga de líneas que no son de caché. Esto puede verse afectado por el tiempo de respuesta del búfer de escritura. Reanudar las asignaciones de escritura después de salir hace que las direcciones de lectura y escritura sean más discontinuas, lo que dificulta la optimización del controlador de memoria, aumenta aún más la latencia y dificulta mantener el modo de transmisión cuando se devuelve al procesador.
Además, el modo streaming tiene un problema, es decir, escribe datos en el caché o memoria del siguiente nivel. ¿Qué pasa si estos datos se van a utilizar inmediatamente? ¿Entonces no hay necesidad de agarrarlo? Para resolver este problema, se introdujo una nueva instrucción de operación de caché DCZVA en el conjunto de instrucciones ARM v8 (para A53/57/72), que puede establecer toda la línea de caché en 0 sin causar asignación de escritura. ¿Por qué? Debido a que lo que se va a cambiar es toda la fila de datos, no un campo determinado, y no es necesario leer el valor original, solo se requiere asignación, no se requiere lectura, pero aún así causará el desalojo.
De manera similar, también podemos borrar e invalidar una parte del caché antes de usarlo, limpiarlo e invalidarlo, por lo que no habrá evidencia. Pero si el bloque de datos de prueba es lo suficientemente grande, esto equivale a un desalojo por adelantado y no se puede eliminar, por lo que la escritura se concentrará en un determinado segmento. Haga que la lectura posterior sea más consistente.
Todo lo anterior es para el caché de primer nivel. El caché de segundo nivel tiene menos control y no se ve muy afectado por el código. Solo configurando el registro, abra el caché de segundo nivel para la captación previa o establezca el desplazamiento de la captación previa. Visto en el controlador de caché L2 PL301 de ARM. Si el desplazamiento se establece bien y los datos capturados se utilizan exactamente, el ancho de banda de lectura se puede aumentar en 150 según el código y la optimización de la caché de primer nivel. En los procesadores nuevos, se pueden realizar múltiples captaciones previas simultáneamente para detectar múltiples conjuntos de plantillas de acceso, lo que mejora aún más la eficiencia. Además, la cantidad de OT adjuntas a cada nivel de caché es definitivamente mayor que el nivel anterior, que incluye varias operaciones de lectura, escritura y caché. Usar bien estos OT puede mejorar el rendimiento.
Las escrituras que no se pueden almacenar en caché se envían directamente desde el búfer de almacenamiento al búfer de escritura para fusionarlas y luego al caché del siguiente nivel. Para lecturas que no se pueden almacenar en caché, decimos que primero irá al caché para ver si hay un acierto. Si no lo logra, leerá directamente el búfer y lo fusionará antes de enviarlo al siguiente caché. Por lo general, no ocupa el búfer de relleno de línea porque suele tener de 4 a 8 bytes y no requiere el uso de un búfer del tamaño de una línea de caché.
A veces también podemos utilizar canales de lectura que no se pueden almacenar en caché para ejecutarlos en paralelo con operaciones de lectura que se pueden almacenar en caché para mejorar la eficiencia. El principio es utilizar tanto el búfer de relleno de línea como el búfer de lectura. En este momento, es necesario asegurarse de que el procesador tenga suficiente OT y no se apague.
En resumen, el principio de optimización del software para el acceso a la memoria es mantener la alineación, encontrar más OT disponibles, combinar el acceso a la memoria y la captación previa, mantener más direcciones de acceso consecutivas y acortar la latencia de cada enlace.
Por último, explique los motivos de los retrasos en el almacenamiento en caché. Lo que quizás los programadores no sepan es que cachés de diferentes tamaños pueden alcanzar diferentes frecuencias de reloj. La caché de primer nivel de ARM es de 32 a 64 KB en el proceso de 16 nm y puede funcionar a alrededor de 1 a 2 Ghz, la misma frecuencia que el procesador. No importa qué tan rápida sea la frecuencia del procesador, acceder al caché requiere de 2 a 3 ciclos de procesador. El caché de segundo nivel es más lento, 256 KB y 800 Mhz es bueno. Esto se debe a que cuanto mayor sea el caché, mayor será el índice del directorio a buscar y cuanto mayor sea el despliegue y la capacitancia, más lento será. Además, existe la premisa de que la latencia de acceso a la caché generalmente se menciona cuando los procesadores están expuestos, es decir, cuando se utiliza el índice de direcciones virtuales VIPT. De esta manera, la dirección del índice se puede obtener directamente sin buscar la tabla Tlb de primer nivel. Si utiliza PIPT de indexación de direcciones físicas, se requiere tiempo adicional para encontrar el tlb de primer nivel para la traducción de virtual a real. Si ocurre un error, debe encontrarse en el segundo nivel o incluso en la tabla de páginas del software. Obviamente eso es demasiado lento. Entonces, ¿por qué no todos usan VIPT? Debido a que VIPT causa problemas, se asignarán varias direcciones virtuales a una dirección real, por lo que varias entradas en la caché corresponderán a una dirección real. Varias entradas pueden provocar errores de coherencia cuando hay escrituras. La caché de instrucciones suele ser de sólo lectura, por lo que no existe tal problema. Por lo tanto, la mayoría de las cachés de instrucciones utilizan VIPT. A medida que aumenta la frecuencia del procesador, el almacenamiento en caché de datos solo puede usar VIPT. Para resolver el problema anterior, ARM agregó lógica adicional al nuevo procesador para detectar entradas duplicadas.
Después de todas las tonterías, toca hablar de la latencia de acceso a la memoria en sistemas reales. Justo encima de la imagen:
En la configuración que se muestra arriba, DDR4 funciona a 3,2 Gbps, con un bus de 800 Mhz, un controlador de memoria de 800 Mhz y un procesador de 2,25 Ghz. Apague el caché y pruebe con las instrucciones de lectura. La latencia incluye tanto la dirección de salida como la de entrada, 69,8 nanosegundos, que es el mejor resultado en el caso de acceder siempre a páginas físicas de memoria. El acceso aleatorio a la dirección tarda 17,5 nanosegundos multiplicados por 2 a 3. Para obtener una explicación de las páginas físicas, consulte el capítulo sobre memoria.
El tiempo que pasa en la memoria es la interfaz de la capa física del controlador, un total de ***38,9 nanosegundos.
55. Si accede a una dirección aleatoria, le llevará más de 70 nanosegundos, lo que representa el 70%. El tiempo transcurrido en el bus y el puente asíncrono es de 20 nanosegundos, 8 ciclos de reloj del bus, 28. Procesador de 11,1 nanosegundos, lo que representa 16,20 ciclos de reloj del procesador.
Por lo tanto, incluso en DDR4 de 3,2 Gbps, la mayor parte del tiempo todavía está en la memoria y, obviamente, la optimización puede comenzar desde aquí. Sólo una pequeña parte del tiempo se dedica al procesador. Pero, por otro lado, el procesador controla el número de rellenos y borrados de filas, la continuidad de las direcciones y la eficiencia de la captación previa. Aunque es el que lleva menos tiempo, también es el foco de la optimización.
En la hoja de ruta de ARM, hay otra tecnología que no es nueva, llamada stashing. Proviene del procesador de red. El principio es que el controlador periférico (PCIe, tarjeta de red) envía una solicitud al procesador y coloca algunos datos en la memoria caché. El proceso es similar al de espiar. En algunas áreas, esta tecnología puede provocar cambios cualitativos. Por ejemplo, los procesadores Intel Xeon y su biblioteca de reenvío de red DPDK pueden recibir paquetes de tarjetas de red PCIe, analizar los encabezados de los paquetes y devolverlos en un promedio de 80 ciclos de procesador. ¿Cuál es el concepto de 80 ciclos? Después de observar el gráfico de latencia de acceso a la memoria anterior, debe saber que el procesador tarda entre 200 y 300 ciclos en acceder a la memoria. Estos datos se envían mediante DMA desde el puerto PCIe a la memoria, luego el procesador los captura y procesa y luego salen del puerto PCIe a través de DMA. Definitivamente todo el proceso llevará más tiempo que el tiempo de acceso a la memoria. Un tiempo promedio de 80 ciclos significa que debe enviarse al caché con anticipación. Sin embargo, hay muchos datos entrantes y solo el controlador PCIe o NIC sabe qué encabezado del paquete puede enviar los datos con precisión; de lo contrario, el caché se inundará con datos inútiles. Una vez realizado este proceso, puede permitir que el software procese Ethernet o unidades de almacenamiento más rápido que los aceleradores de hardware. De hecho, en los procesadores de red de Freescale, con la ayuda de aceleradores de hardware, el retraso promedio en el procesamiento de paquetes de datos requiere 200 ciclos de procesador, lo que ya es más lento que el de Xeon.
Además, los nuevos núcleos de ARM orientados a la red y al servidor tendrán un diseño de un núcleo y dos subprocesos. La tarea de procesar paquetes es naturalmente adecuada para subprocesos múltiples. Un núcleo y dos subprocesos pueden hacer un uso más eficiente de los recursos de hardware. Con la adición de almacenamiento oculto, es aún más poderoso. (Publicado desde Jugando con el microcontrolador)
1. Publicaciones electrónicas, ¡también podrías obtener una parte del pastel!
2,35 años, ¡un tema eterno entre los ingenieros!
3. No ofendas a los programadores. La venganza es muy cruel. ¡11 líneas de código te harán dudar de tu vida!
4. Ingenieros de software versus ingenieros de hardware, ¿a cuál servirá en el futuro?
5. Descripción general de los protocolos de IoT integrados
6. ¿Cuál es la dirección del desarrollo profesional en el campo integrado?
Descargo de responsabilidad: este artículo se reproduce en línea y los derechos de autor pertenecen al autor original. Si los derechos de autor del trabajo están involucrados, comuníquese con nosotros. Confirmaremos los derechos de autor y pagaremos las regalías o eliminaremos el contenido según los materiales de certificación de derechos de autor que proporcione.