Kaynak belleği cpu önbelleğine yüklemeyen bir memcpy işlevi yazmaya çalışıyorum. Amaç, önbellek kirliliğinden kaçınmaktır. Aşağıdaki memcpy işlevi çalışır, ancak önbelleği standart memcpy'nin yaptığı gibi kirletir. Visual C++ 2008 express ile P8700 proccesoor kullanıyorum. cpu önbellek kullanımını intel vtune ile görüyorum.Önbellek kirliliği önlemek için movntdqa nasıl kullanılır?
Aynı sonuçlara sahip başka bir sürümüm var - çalışır ancak önbelleği kirletir.
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
}
}
güncelleme: Bu Intel den aktaran test programı
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)
}
Not 4 KiB'den fazla veri kopyalamak neredeyse hiç gerçekleşmez. büyük miktarda veri için (küçük bellek kopyaları için daha yavaş hale getiren başlangıç ek yükü pahasına) mcpy() 'dır ve aptallığınız gerçek dünya yazılımları için performansı daha da kötüleştirir. – Brendan