Why is the auto-vectorized version of this program fragment slower than the simple version
<p>In a larger numerical computation, I have to perform the trivial task of summing up the products of the elements of two vectors. Since this task needs to be done very often, I tried to make use of the auto vectorization capabilities of my compiler (VC2015). I introduced a temporary vector, where the products are saved in in a first loop and then performed the summation in a second loop. Optimization was set to full and fast code was preferred. This way, the first loop got vectorized by the compiler (I know this from the compiler output). </p>

<p>The result was surprising. The vectorized code performed 3 times slower on my machine (core i5-4570 3.20 GHz) than the simple code. Could anybody explain why and what might improve the performance? I've put both versions of the algorithm fragment into a minimal running example, which I used myself for testing:</p>

<pre><code>#include "stdafx.h"
#include &lt;vector&gt;
#include &lt;Windows.h&gt;
#include &lt;iostream&gt;

using namespace std;

int main()
{
    // Prepare timer
    LARGE_INTEGER freq,c_start,c_stop;
    QueryPerformanceFrequency(&amp;freq);

    int size = 20000000; // size of data
    double v = 0;

    // Some data vectors. The data inside doesn't matter
    vector&lt;double&gt; vv(size);
    vector&lt;double&gt; tt(size);
    vector&lt;float&gt; dd(size);

    // Put random values into the vectors
    for (int i = 0; i &lt; size; i++)
    {
        tt[i] = rand();
        dd[i] = rand();
    }

    // The simple version of the algorithm fragment
    QueryPerformanceCounter(&amp;c_start); // start timer
    for (int p = 0; p &lt; size; p++)
    {
        v += tt[p] * dd[p];
    }
    QueryPerformanceCounter(&amp;c_stop); // Stop timer

    cout &lt;&lt; "Simple version took: " &lt;&lt; ((double)(c_stop.QuadPart - c_start.QuadPart)) / ((double)freq.QuadPart) &lt;&lt; " s" &lt;&lt; endl;
    cout &lt;&lt; v &lt;&lt; endl; // We use v once. This avoids its calculation to be optimized away.

    // The version that is auto-vectorized

    for (int i = 0; i &lt; size; i++)
    {
        tt[i] = rand();
        dd[i] = rand();
    }

    v = 0;
    QueryPerformanceCounter(&amp;c_start); // start timer
    for (int p = 0; p &lt; size; p++) // This loop is vectorized according to compiler output
    {
        vv[p] = tt[p] * dd[p];
    }
    for (int p = 0; p &lt; size; p++)
    {
        v += vv[p];
    }
    QueryPerformanceCounter(&amp;c_stop); // Stop timer

    cout &lt;&lt; "Vectorized version took: " &lt;&lt; ((double)(c_stop.QuadPart - c_start.QuadPart)) / ((double)freq.QuadPart) &lt;&lt; " s" &lt;&lt; endl;
    cout &lt;&lt; v &lt;&lt; endl; // We use v once. This avoids its calculation to be optimized away.

    cin.ignore();

    return 0;
}
</code></pre>