cómo utilizar movntdqa para evitar la contaminación de caché?
Pregunta
Estoy tratando de escribir una función de establecimiento de memoria que no se carga la memoria de origen a la caché de la CPU. El propósito es evitar la contaminación de caché. La función memcpy a continuación funciona, pero contamina el caché como el establecimiento de memoria estándar hace. estoy usando P8700 proccesoor con Visual C ++ 2008 Express. Veo el uso de la caché de la CPU con Intel VTune.
void memcpy(char *dst,char*src,unsigned size){
char *dst_end=dst+size;
while(dst!=dst_end){
__m128i res = _mm_stream_load_si128((__m128i *)src);
*((__m128i *)dst)=res;
src+=16;
dst+=16;
}
}
Tengo otra versión, que tiene los mismos resultados -. Obras, sino contamina el caché
void memcpy(char *dst,char*src,unsigned size){
char *dst_end = dst+size;
__asm{
mov edi, dst
mov edx, dst_end
mov esi,src
inner_start:
LFENCE
MOVNTDQA xmm0, [esi ]
MOVNTDQA xmm1, [esi+16]
MOVNTDQA xmm2, [esi+32]
MOVNTDQA xmm3, [esi+48]
//19. ; Copy data to buffer
MOVDQA [edi], xmm0
MOVDQA [edi+16], xmm1
MOVDQA [edi+32], xmm2
MOVDQA [edi+48], xmm3
// 25. ; Increment pointers by cache line size and test for end of loop
add esi, 040h
add edi, 040h
cmp edi, edx
jne inner_start
}
}
Actualización: este es el programa de prueba
void test(int table_size,int num_iter,int item_size){
char *src_table=alloc_aligned(table_size*item_size);//return value is aligned on 64 bytes
char *dst=alloc_aligned(item_size); //destination is always the same buffer
for (int i=0;i<num_iter;i++){
int location=my_rand()%table_size;
char *src=src_table+location*item_size;//selecting a different src every time
memcpy(dst,src,item_size);
}
}
main(){
test(1024*32,1024*1024,1024*32)
}
Solución
Citando Intel :
"La instrucción de carga es de streaming cuyo objetivo es acelerar la transferencia de datos a partir del tipo de memoria USWC. Por otro tipos de memoria, tal como cacheable (BM) o No almacenable en caché (UC), la instrucción se comporta como un típico MOVDQA de 16 bytes instrucción de carga. Sin embargo, el futuro procesadores pueden utilizar la carga de streaming instrucciones para otros tipos de memoria (Tales como WB) como un indicio de que la línea de caché destinada debería ser escuchados de la memoria directamente al núcleo mientras minimización de la contaminación de caché ".
Esto explica por qué el código no funciona - la memoria es de tipo BM
.