title: x86 assembly instructions optimisation
body: <p>I'm trying to optimize a block of instructions in a loop, called thousands of time, which is the bottleneck in my algorithm.</p>
  
  <p>This block of code compute the multiplication of a N matrices 3x3 (iA array) against N vectors 3 (iV array) and store the N results in oV array. (N is not fix and is usually between 3000 and 15000)</p>
  
  <p>Each line of matrices and vectors are 128-bits aligned (4 floats) to exploit SSE optimisation (the 4th floating value is ignored).</p>
  
  <p>C++ code :</p>
  
  <pre><code>  __m128* ip = (__m128*)iV;
    __m128* op = (__m128*)oV;
    __m128* A = (__m128*)iA;
  
    __m128 res1, res2, res3;
    int i;
  
    for (i=0; i&lt;N; i++)
    {
      res1 = _mm_dp_ps(*A++, *ip, 0x71);
      res2 = _mm_dp_ps(*A++, *ip, 0x72);
      res3 = _mm_dp_ps(*A++, *ip++, 0x74);
  
      *op++ = _mm_or_ps(res1, _mm_or_ps(res2, res3));
    }
  </code></pre>
  
  <p>The compiler generates these instructions :</p>
  
  <pre><code>000007FEE7DD4FE0  movaps      xmm2,xmmword ptr [rsi]               //move "ip" in register
  000007FEE7DD4FE3  movaps      xmm1,xmmword ptr [rdi+10h]           //move second line of A in register
  000007FEE7DD4FE7  movaps      xmm0,xmmword ptr [rdi+20h]           //move third line of A in register
  000007FEE7DD4FEB  inc         r11d                                 //i++
  000007FEE7DD4FEE  add         rbp,10h                              //op++
  000007FEE7DD4FF2  add         rsi,10h                              //ip++
  000007FEE7DD4FF6  dpps        xmm0,xmm2,74h                        //dot product of 3rd line of A against ip
  000007FEE7DD4FFC  dpps        xmm1,xmm2,72h                        //dot product of 2nd line of A against ip
  000007FEE7DD5002  orps        xmm0,xmm1                            //"merge" of the result of the two dot products
  000007FEE7DD5005  movaps      xmm3,xmmword ptr [rdi]               //move first line of A in register
  000007FEE7DD5008  add         rdi,30h                              //A+=3
  000007FEE7DD500C  dpps        xmm3,xmm2,71h                        //dot product of 1st line of A against ip
  000007FEE7DD5012  orps        xmm0,xmm3                            //"merge" of the result
  000007FEE7DD5015  movaps      xmmword ptr [rbp-10h],xmm0           //move result in memory (op)
  000007FEE7DD5019  cmp         r11d,dword ptr [rbx+28h]             //compare i
  000007FEE7DD501D  jl          MyFunction+370h (7FEE7DD4FE0h)       //loop
  </code></pre>
  
  <p>I'm not very familiar with low-level optimisations, so the question is : Do you see some possible optimisations if I write assembly code myself ?</p>
  
  <p>For example, will it run faster if I change :</p>
  
  <pre><code>add         rbp,10h
  movaps      xmmword ptr [rbp-10h],xmm0
  </code></pre>
  
  <p>by</p>
  
  <pre><code>movaps      xmmword ptr [rbp],xmm0
  add         rbp,10h
  </code></pre>
  
  <p>I have also read that ADD instruction is faster than INC...</p>