title: Using AVX intrinsics instead of SSE does not improve speed -- why?
body: <p>I've been using Intel's SSE intrinsics for quite some time with good performance gains. Hence, I expected the AVX intrinsics to further speed-up my programs. This, unfortunately, was not the case until now. Probably I am doing a stupid mistake, so I would be very grateful if somebody could help me out.</p>
  
  <p>I use Ubuntu 11.10 with g++ 4.6.1. I compiled my program (see below) with </p>
  
  <pre><code>g++ simpleExample.cpp -O3 -march=native -o simpleExample
  </code></pre>
  
  <p>The test system has a Intel i7-2600 CPU.</p>
  
  <p>Here is the code which exemplifies my problem. On my system, I get the output</p>
  
  <pre><code>98.715 ms, b[42] = 0.900038 // Naive
  24.457 ms, b[42] = 0.900038 // SSE
  24.646 ms, b[42] = 0.900038 // AVX
  </code></pre>
  
  <p>Note that the computation sqrt(sqrt(sqrt(x))) was only chosen to ensure that memory bandwith does not limit execution speed; it is just an example. </p>
  
  <p>simpleExample.cpp:</p>
  
  <pre><code>#include &lt;immintrin.h&gt;
  #include &lt;iostream&gt;
  #include &lt;math.h&gt; 
  #include &lt;sys/time.h&gt;
  
  using namespace std;
  
  // -----------------------------------------------------------------------------
  // This function returns the current time, expressed as seconds since the Epoch
  // -----------------------------------------------------------------------------
  double getCurrentTime(){
    struct timeval curr;
    struct timezone tz;
    gettimeofday(&amp;curr, &amp;tz);
    double tmp = static_cast&lt;double&gt;(curr.tv_sec) * static_cast&lt;double&gt;(1000000)
               + static_cast&lt;double&gt;(curr.tv_usec);
    return tmp*1e-6;
  }
  
  // -----------------------------------------------------------------------------
  // Main routine
  // -----------------------------------------------------------------------------
  int main() {
  
    srand48(0);            // seed PRNG
    double e,s;            // timestamp variables
    float *a, *b;          // data pointers
    float *pA,*pB;         // work pointer
    __m128 rA,rB;          // variables for SSE
    __m256 rA_AVX, rB_AVX; // variables for AVX
  
    // define vector size 
    const int vector_size = 10000000;
  
    // allocate memory 
    a = (float*) _mm_malloc (vector_size*sizeof(float),32);
    b = (float*) _mm_malloc (vector_size*sizeof(float),32);
  
    // initialize vectors //
    for(int i=0;i&lt;vector_size;i++) {
      a[i]=fabs(drand48());
      b[i]=0.0f;
    }
  
  // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  // Naive implementation
  // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    s = getCurrentTime();
    for (int i=0; i&lt;vector_size; i++){
      b[i] = sqrtf(sqrtf(sqrtf(a[i])));
    }
    e = getCurrentTime();
    cout &lt;&lt; (e-s)*1000 &lt;&lt; " ms" &lt;&lt; ", b[42] = " &lt;&lt; b[42] &lt;&lt; endl;
  
  // -----------------------------------------------------------------------------
    for(int i=0;i&lt;vector_size;i++) {
      b[i]=0.0f;
    }
  // -----------------------------------------------------------------------------
  
  // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  // SSE2 implementation
  // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    pA = a; pB = b;
  
    s = getCurrentTime();
    for (int i=0; i&lt;vector_size; i+=4){
      rA   = _mm_load_ps(pA);
      rB   = _mm_sqrt_ps(_mm_sqrt_ps(_mm_sqrt_ps(rA)));
      _mm_store_ps(pB,rB);
      pA += 4;
      pB += 4;
    }
    e = getCurrentTime();
    cout &lt;&lt; (e-s)*1000 &lt;&lt; " ms" &lt;&lt; ", b[42] = " &lt;&lt; b[42] &lt;&lt; endl;
  
  // -----------------------------------------------------------------------------
    for(int i=0;i&lt;vector_size;i++) {
      b[i]=0.0f;
    }
  // -----------------------------------------------------------------------------
  
  // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  // AVX implementation
  // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    pA = a; pB = b;
  
    s = getCurrentTime();
    for (int i=0; i&lt;vector_size; i+=8){
      rA_AVX   = _mm256_load_ps(pA);
      rB_AVX   = _mm256_sqrt_ps(_mm256_sqrt_ps(_mm256_sqrt_ps(rA_AVX)));
      _mm256_store_ps(pB,rB_AVX);
      pA += 8;
      pB += 8;
    }
    e = getCurrentTime();
    cout &lt;&lt; (e-s)*1000 &lt;&lt; " ms" &lt;&lt; ", b[42] = " &lt;&lt; b[42] &lt;&lt; endl;
  
    _mm_free(a);
    _mm_free(b);
  
    return 0;
  }
  </code></pre>
  
  <p>Any help is appreciated!</p>