Why is calculating each matrix column faster than using matrix product?

Viewed 166
#include <Eigen/Dense>
#include <ctime>
#include <iostream>

using namespace std;
using namespace Eigen;

void slow(const Matrix<std::complex<float>, 20, 1> &a, const Matrix<float, 1, 2> &b, Matrix<std::complex<float>, 20, 2> &out)
{
    out.noalias() += a * b;
}

void fast(const Matrix<std::complex<float>, 20, 1> &a, const Matrix<float, 1, 2> &b, Matrix<std::complex<float>, 20, 2> &out)
{
    for (size_t i = 0; i < 2; ++i)
    {
        out.col(i).noalias() += a * b[i];
    }
}

int main(int, const char**)
{
    clock_t start;
    Matrix<std::complex<float>, 20, 2> out;
    Matrix<std::complex<float>, 20, 1> a;
    Matrix<float, 1, 2> b;
    a = a.Random();
    b = b.Random();
    out.setZero();

    start = clock();
    const size_t N = 10000000;
    for( size_t i = 0; i < N; ++i )
    { 
        slow(a, b, out);
    }
    cout << "Matrix norm: " << out.norm() << endl;
    cout << "Slow: " << (std::clock() - start) / (double)(CLOCKS_PER_SEC / 1000) << " ms" << endl;

    out.setZero();
    start = clock();
    for (size_t i = 0; i < N; ++i)
    {
        fast(a, b, out);
    }
    cout << "Matrix norm: " << out.norm() << endl;
    cout << "Fast: " << (clock() - start) / (double)(CLOCKS_PER_SEC / 1000) << " ms" << endl;

    return 0;
}

I have compiled the above code using Visual Studio 2017, Eigen 3.3.7 and with the following compiler flags:

/O2 /fp:fast /arch:AVX2

Here is the output of the program:

Matrix norm: 3.07615e+07
Slow: 6707 ms
Matrix norm: 3.07615e+07
Fast: 230 ms

The function "fast" and "slow" compute the same result. Why is the "slow" function slower than the "fast" function?

0 Answers
Related