本文介绍了如何使用movntdqa避免缓存污染?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想写一个不来源存储器装载到CPU缓存memcpy函数。的目的是为了避免缓存污染。
下面的memcpy函数的作品,但像标准的memcpy确实污染缓存。我使用P8700 proccesoor用Visual C ++ 2008的前preSS。我看到英特尔VTune CPU的缓存使用。

 无效的memcpy(字符* DST,字符* SRC,无符号大小){
    字符* dst_end = DST +大小;
    而(DST!= dst_end){
    __m128i解析度= _mm_stream_load_si128((__ m128i *)SRC);
    *((__ m128i *)DST)=资源;
    SRC + = 16;
    DST + = 16;
    }
}

我有另一个版本,具有相同的结果 - 工作但污染缓存

 无效的memcpy(字符* DST,字符* SRC,无符号大小){        字符* dst_end = DST +大小;        __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。 ;数据复制到缓冲区
      MOVDQA [EDI],XMM0
      MOVDQA [EDI + 16],将xmm1
      MOVDQA [EDI + 32],XMM2
      MOVDQA [EDI + 48],XMM3
    // 25;增量指针由高速缓存行的大小和测试循环结束
      加ESI,040H
      加入EDI,040H
      CMP EDI,EDX
      JNE inner_start
}
}

更新:这是测试程序

 无效测试(INT table_size,诠释num_iter,诠释item_size){
            字符* src_table = alloc_aligned(table_size * item_size); //返回值是在64字节对齐
            字符* DST = alloc_aligned(item_size); //目的地总是相同的缓冲液
            的for(int i = 0; I< num_iter;我++){
                INT位置= my_rand()%table_size;
                字符* SRC = src_table +位置* item_size; //选择不同的SRC每次
                的memcpy(DST,SRC,item_size);
            }        }
主要(){
       试验(1024 * 32,1024 * 1024,1024 * 32)
}


解决方案

从intel

that explains why the code does not work - the memory is of type wb.

这篇关于如何使用movntdqa避免缓存污染?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-17 18:40
查看更多