2008-08-31 12 views
81

Ésta es una pregunta un tanto de bajo nivel. En el montaje 86 hay dos instrucciones SSE:¿Cuál es el significado de la memoria "no temporal" de accesos en x86

MOVDQA xmmi, m128

y

Manual MOVNTDQA xmmi, m128

El IA-32 software del desarrollador dice que el NT en MOVNTDQA significa Non -Temporal, y que de lo contrario es lo mismo que MOVDQA.

Mi pregunta es, ¿qué significa no temporal?

+1

Tenga en cuenta que SSE4.1 'MOVNTDQA XMMI, m128' es una carga NT, mientras que todas las demás instrucciones NT son las tiendas, a excepción de' prefetchnta'. La respuesta aceptada aquí solo parece estar hablando de tiendas. [Esto es lo que he podido mostrar sobre las cargas NT] (http://stackoverflow.com/questions/32103968/non-temporal-loads-and-the-hardware-prefetcher-do-they-work-together) TL: DR: es de esperar que la CPU haga algo útil con la sugerencia de NT para minimizar la contaminación de la memoria caché, pero no anulan la semántica fuertemente ordenada de la memoria WB "normal", por lo que tienen que usar la memoria caché. –

+1

Actualización: NT * cargas * puede no hacer nada útil, excepto en las regiones de memoria UCSW en la mayoría de las CPU (por ejemplo, la familia Intel SnB). NT/streaming * stores * definitivamente funcionan en la memoria normal, sin embargo. –

+0

@Peter: ¿Te refieres a la memoria de USWC, verdad?Nunca había oído hablar de UCSW o memoria USWC antes. Buscar en Google el acrónimo incorrecto no fue útil :-) –

Respuesta

106

instrucciones SSE no temporal (MOVNTI, MOVNTQ, etc.), no siguen las reglas normales de caché de coherencia. Por lo tanto, los almacenes no temporales deben ir seguidos de una instrucción SFENCE para que sus resultados puedan ser vistos por otros procesadores de manera oportuna.

Cuando los datos se produce y no (inmediatamente) consume más, el hecho de que las operaciones de almacenamiento de memoria caché de leer una línea completa primero y luego modificar los datos en caché es perjudicial para el rendimiento. Esta operación saca los datos de las memorias caché que podrían necesitarse de nuevo a favor de datos que no se usarán pronto. Esto es especialmente cierto para estructuras de datos grandes, como matrices, que se llenan y luego se usan. Antes de que se llene el último elemento de la matriz, el tamaño puro expulsa los primeros elementos, haciendo que el almacenamiento en caché de las escrituras sea ineficaz.

Por esta y otras situaciones similares, los procesadores proporcionan apoyo a las operaciones de escritura no temporales. No temporal en este contexto significa que los datos no serán reutilizados pronto, por lo que no hay razón para almacenarlos en caché. Estas operaciones de escritura no temporales no leen una línea de caché y luego la modifican; en cambio, el nuevo contenido se escribe directamente en la memoria.

Fuente: http://lwn.net/Articles/255364/

+10

Una buena respuesta, me gustaría señalar que en el tipo de procesador con instrucciones NT, incluso con una instrucción no temporal (es decir, una instrucción normal), la línea el caché no es "leído y luego modificado". Para una instrucción normal que se escribe en una línea que no está en el caché, se reserva una línea en el caché y una máscara indica qué partes de la línea están actualizadas. Esta página web lo llama "sin puesto en la tienda": http://www.ptlsim.org/Documentation/html/node30.html. No pude encontrar referencias más precisas, solo escuché sobre esto de chicos cuyo trabajo es implementar simuladores de procesador. –

+2

En realidad, http://www.ptlsim.org/ es un sitio web sobre un simulador de procesador con precisión de ciclo, exactamente el mismo tipo de cosas que los tipos que me dijeron sobre "no hay puesto en la tienda" lo están haciendo. Será mejor que los mencione también en caso de que alguna vez vean este comentario: http://unisim.org/ –

+0

De las respuestas y comentarios aquí https://stackoverflow.com/questions/44864033/make-previous-memory-stores- cargas de memoria visibles a posteriores parece que 'SFENCE' puede no ser necesario. Al menos en el mismo hilo. ¿También podrías mirar? –

29

Espo es más o menos lleno en la diana. Sólo quería añadir mi granito de arena:

La frase "no temporal" que carecen localidad temporal. Los cachés explotan dos tipos de localidad: espacial y temporal, y al usar una instrucción no temporal le indica al procesador que no espera que el elemento de datos se use en el futuro cercano.

Soy un poco escéptico sobre el conjunto codificado a mano que utiliza las instrucciones de control de caché. En mi experiencia, estas cosas conducen a más errores malvados que cualquier rendimiento efectivo aumenta.

+0

pregunta sobre "ensamblado codificado a mano que utiliza las instrucciones de control de caché". Sé que usted dijo explícitamente "codificado a mano" qué pasa con algo así como un JavaVM. ¿Es este un mejor caso de uso? El JavaVM/Compiler ha analizado el comportamiento estático y dinámico del programa y utiliza estas instrucciones no temporales. – Pat

+1

No debe evitarse la explotación de propiedades de localidad conocidas (o la falta de ellas) de su dominio problemático, algoritmo o aplicación. Evitar la contaminación del caché es una tarea de optimización muy atractiva y efectiva. Además, ¿por qué la aversión hacia el ensamblaje? Hay una gran cantidad de oportunidades de ganancias disponibles que un compilador no puede capitalizar en –

+3

. Definitivamente es cierto que un programador conocedor de bajo nivel puede superar el rendimiento de un compilador de kernels pequeños. Esto es excelente para publicar trabajos y publicaciones de blog, y he hecho ambas cosas. También son buenas herramientas didácticas y ayudan a comprender qué está sucediendo realmente. En mi experiencia, sin embargo, en la práctica, donde tienes un sistema real con muchos programadores trabajando en él y la corrección y mantenibilidad son importantes, el beneficio de la codificación de bajo nivel casi siempre se ve compensado por los riesgos. – Pramod

Cuestiones relacionadas