ソースメモリをCPUキャッシュにロードしないmemcpy関数を書き込もうとしています。キャッシュの汚染を避けることを目的としています。 以下のmemcpy関数は機能しますが、標準のmemcpyのようにキャッシュを汚染します。私はVisual C++ 2008 ExpressでP8700 proccesoorを使用しています。私はintel vtuneでCPUキャッシュの使用を見ます。動作しますが、キャッシュを汚染 -キャッシュ汚染を避けるためにmovntdqaを使用する方法は?
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
}
}
更新:これはIntelから引用テストプログラム
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)
}
注意4KiB以上のデータをコピーすることはほとんどありません。膨大な量のデータ(スタートアップオーバーヘッドを犠牲にして、小さなメモリコピーの速度を遅くする)のためのmcpy()は愚かであり、あなたの最適化は実世界のソフトウェアのパフォーマンスを悪化させます。 – Brendan