Skip to content

Instantly share code, notes, and snippets.

@alexshen
Last active August 29, 2015 13:57
Show Gist options
  • Save alexshen/9781052 to your computer and use it in GitHub Desktop.
Save alexshen/9781052 to your computer and use it in GitHub Desktop.
#include <xmmintrin.h>
#include <chrono>
#include <iostream>
using namespace std;
using namespace chrono;
#ifdef _MSC_VER
__declspec(align(16)) struct vector4
#else
struct alignas(16) vector4
#endif
{
float v[4];
};
template<int N>
struct dot_unroller;
template<>
struct dot_unroller<1>
{
static float eval(float const* v1, float const* v2)
{
return *v1 * *v2;
}
};
template<int N>
struct dot_unroller
{
static float eval(float const* v1, float const* v2)
{
return dot_unroller<1>::eval(v1, v2) + dot_unroller<N - 1>::eval(v1 + 1, v2 + 1);
}
};
float dot_std(vector4 const& v1, vector4 const& v2)
{
return dot_unroller<4>::eval(v1.v, v2.v);
}
float dot_unroll(vector4 const& v1, vector4 const& v2)
{
return v1.v[0] * v2.v[0] +
v1.v[1] * v2.v[1] +
v1.v[2] * v2.v[2] +
v1.v[3] * v2.v[3];
}
float dot_sse(vector4 const& v1, vector4 const& v2)
{
#ifdef _MSC_VER
__declspec(align(16)) float r[4];
#else
alignas(16) float r[4];
#endif
__m128 a, b;
a = _mm_load_ps(v1.v);
b = _mm_load_ps(v2.v);
_mm_store_ps(r, _mm_mul_ps(a, b));
return r[0] + r[1] + r[2] + r[3];
}
struct timer
{
char const* name;
high_resolution_clock::time_point start;
timer(char const* p)
: name{ p }
, start{ high_resolution_clock::now() }
{
}
~timer()
{
auto duration = high_resolution_clock::now() - start;
cout << name << ": " << duration_cast<nanoseconds>(duration).count() << endl;
}
};
template<typename F>
void time_it(char const* name, F f, int count)
{
float res;
{
timer t{ name };
vector4 a = { 1, 2, 3, 4 };
for (int i = 0; i < count; ++i)
{
res = f(a, a);
}
}
cout << res << endl;
}
int main()
{
int const count = 1000000;
for (int i = 0; i < 3; ++i)
{
time_it("dot_std", dot_std, count);
time_it("dot_unroll", dot_unroll, count);
time_it("dot_sse", dot_sse, count);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment