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)
}
¿Fue útil?

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

.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top