2009-05-12 18 views
11

ソースメモリを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) 
} 
+1

注意4KiB以上のデータをコピーすることはほとんどありません。膨大な量のデータ(スタートアップオーバーヘッドを犠牲にして、小さなメモリコピーの速度を遅くする)のためのmcpy()は愚かであり、あなたの最適化は実世界のソフトウェアのパフォーマンスを悪化させます。 – Brendan

答えて

8

ある:

「ストリーミングロード命令がUSWCメモリタイプからデータ転送 を促進することを意図し あります。キャッシュ可能(WB)または キャッシュ不可(UC)などの他の メモリタイプの場合、命令 は、ロード命令の典型的な16バイトMOVDQA として動作します。しかしながら、将来 プロセッサは がキャッシュ汚染を最小限に抑えながら 意図キャッシュラインを直接コアにメモリから をストリーミングする必要があることをヒントとして (例えばWBのような)他のメモリタイプのストリーミング負荷 命令を使用することができる。」

コードが動作しない理由を説明

- 。メモリはタイプWBであるあなたは、実際にソフトウェアのいくつかの大規模な作品を勉強すれば、あなたはほとんどのメモリコピーが実際に32バイト未満をコピーしていることを見つけること

+0

このソリューションがうまくいけば(MOVNTDQAは機能しません)、他の人が一目でわかるように、この解決策を承認済みとしてマークしてください。 – klickverbot

関連する問題