캐시 오염을 피하기 위해 MOVNTDQA를 사용하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/851286

  •  21-08-2019
  •  | 
  •  

문제

소스 메모리를 CPU 캐시에로드하지 않는 Memcpy 함수를 작성하려고합니다. 목적은 캐시 오염을 피하는 것입니다. 아래의 Memcpy 기능은 작동하지만 표준 Memcpy와 같이 캐시를 오염시킵니다. Visual C ++ 2008 Express와 함께 P8700 Proccesoor를 사용하고 있습니다. Intel Vtune의 CPU 캐시 사용을 볼 수 있습니다.

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;
    }
}

다른 버전이 있는데, 같은 결과는 동일하지만 작동하지만 캐시를 오염시킵니다.

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 


}
}

업데이트 : 이것은 테스트 프로그램입니다

        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)
}
도움이 되었습니까?

해결책

인용 인텔:

"스트리밍로드 명령어는 USWC 메모리 유형에서 데이터 전송을 가속화하기위한 것입니다. 캐시 가능 (WB) 또는 UCCHER (UCCHANCEBLE) (UC)와 같은 다른 메모리 유형의 경우 명령어는 일반적인 16 바이트 MOVDQA로드 명령어로 작동합니다. 캐시 오염을 최소화하면서 의도 된 캐시 라인이 메모리에서 코어로 직접 스트리밍되어야한다는 힌트로 다른 메모리 유형 (예 : WB)의 스트리밍로드 명령을 사용할 수 있습니다. "

코드가 작동하지 않는 이유를 설명합니다. 메모리는 유형 WB입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top