1. 程式人生 > >intel指令優化

intel指令優化

程式優化

預讀指令讀記憶體

提前預取記憶體中資料到CACHE內,提高CACHE的命中率,加速記憶體讀取速度,這是設計預讀指令的主要目的。
prefetch0、prefetch1、prefetch2、 prefetchnta。
預取指令只是給CPU一個提示,所以它可被CPU忽略,而且就算預取一段錯誤的地址也不會導致CPU異常。一般使用prefetchnta預取指令,因為它不會汙染CACHE,它把每次取得的資料都存放到L2 CACHE的第一條CACHE LINE(不同的cpu不一樣 ),而另外幾條指令會替換CACHE中最近最少使用的CACHE LINE。

非暫時移動指令寫記憶體

我們知道為了保證CACHE與記憶體之間的資料一致性,CPU對CACHE的寫操作主要有兩種方式同步到記憶體,寫透式(Write Through)和寫回式(Write-back)。不管哪種同步方式都是要消耗效能的,而在某些情況下,寫CACHE是不必要的:
有哪些情況不需要寫CACHE呢?比如做資料拷貝(高效memcpy函式實現)時,或者我們已經知道寫的資料在最近一段時間內(或者永遠)都不會再使用了,那麼此時就可以不用寫CACHE,讓對應的CACHE LINE自動失效,以便快取其它資料。這在某些特殊場景非常有用,相應的彙編指令有movntq、movntsd、movntss、movntps、movntpd、movntdq、movntdqa。

完整的利用預讀指令和非暫時移動指令實現的高速記憶體拷貝函式。

void X_aligned_memcpy_sse2(void* dest, const void* src, const unsigned long size_t)
{
  __asm
  {
    mov esi, src;    //src pointer
    mov edi, dest;   //dest pointer
    mov ebx, size_t; //ebx is our counter 
    shr ebx, 7;      //divide by 128 (8 * 128bit registers)

    loop_copy:
      prefetchnta 128
[ESI];
//SSE2 prefetch prefetchnta 160[ESI]; prefetchnta 192[ESI]; prefetchnta 224[ESI]; movdqa xmm0, 0[ESI]; //move data from src to registers movdqa xmm1, 16[ESI]; movdqa xmm2, 32[ESI]; movdqa xmm3, 48[ESI]; movdqa xmm4, 64[ESI]; movdqa xmm5, 80[ESI]; movdqa xmm6, 96[ESI]
; movdqa xmm7, 112[ESI]; movntdq 0[EDI], xmm0; //move data from registers to dest movntdq 16[EDI], xmm1; movntdq 32[EDI], xmm2; movntdq 48[EDI], xmm3; movntdq 64[EDI], xmm4; movntdq 80[EDI], xmm5; movntdq 96[EDI], xmm6; movntdq 112[EDI], xmm7; add esi, 128; add edi, 128; dec ebx; jnz loop_copy; //loop please loop_copy_end: } }

參考:我的第一份實習工作師父的部落格 youfu blog