come utilizzare movntdqa per evitare l'inquinamento della cache?
Domanda
sto cercando di scrivere una funzione memcpy che non caricare la memoria sorgente alla cache della CPU. Lo scopo è quello di evitare l'inquinamento della cache. La funzione memcpy seguito funziona, ma inquina la cache come il memcpy normale fa. Sto usando P8700 proccesoor con Visual C ++ 2008 Express. vedo l'utilizzo della cache 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;
}
}
Ho un'altra versione, che hanno gli stessi risultati -. Opere, ma inquina la cache
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
}
}
Aggiornamento: questo è il programma di test
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)
}
Soluzione
Citando Intel :
"L'istruzione carico streaming è destinato ad accelerare il trasferimento dei dati dal tipo di memoria USWC. Per altro tipi di memoria come cacheable (WB) o Uncacheable (UC), l'istruzione si comporta come una tipica MOVDQA 16 byte istruzione carico. Tuttavia, il futuro processori possono utilizzare il carico di streaming istruzioni per altri tipi di memoria (Come WB) come un suggerimento che il linea di cache destinato dovrebbe essere in streaming dalla memoria direttamente al nucleo mentre riducendo al minimo l'inquinamento della cache ".
Questo spiega perché il codice non funziona - la memoria è di tipo WB
.