Skip to content

Instantly share code, notes, and snippets.

@daramkun
Last active October 16, 2017 06:43
Show Gist options
  • Save daramkun/72c25a505c12ae0f35572798af7ccf73 to your computer and use it in GitHub Desktop.
Save daramkun/72c25a505c12ae0f35572798af7ccf73 to your computer and use it in GitHub Desktop.
SSE Operation Test
////////////////////////////////////////////////////////////////////////////////////////////////////
// Some Source code from https://gist.github.com/rygorous/4172889/3aff2b797b9be7ac261115a95f8d6f6fa32ed54d
//
// You need Intel Haswell Architecture(only Core-i & Xeon) or AMD Piledriver Architecture Processor.
// Because there is no FMA 3 operator in earlier than those.
////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma optimize ( "", off )
#include <cstdio>
#include <iostream>
#include <cstdint>
#include <functional>
#include <Windows.h>
#include <intrin.h>
#include <mmintrin.h>
#include <emmintrin.h>
#include <immintrin.h>
#include <pmmintrin.h>
#include <smmintrin.h>
#include <xmmintrin.h>
volatile uint64_t getCPUCycle () noexcept { return __rdtsc (); }
inline double getCurrentTime () noexcept
{
LARGE_INTEGER performanceFrequency, getTime;
QueryPerformanceFrequency ( &performanceFrequency );
QueryPerformanceCounter ( &getTime );
return ( getTime.QuadPart / ( double ) performanceFrequency.QuadPart );
}
struct Matrix
{
union
{
float arr [ 16 ];
struct { float m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44; };
__m128 sse [ 4 ];
__m256 avx [ 2 ];
} __declspec ( align ( 4 ) );
inline void print ( std::string & name ) noexcept
{
printf (
/*"-- %s --\n"
"%5.2f, %5.2f, %5.2f, %5.2f\n"
"%5.2f, %5.2f, %5.2f, %5.2f\n"
"%5.2f, %5.2f, %5.2f, %5.2f\n"
"%5.2f, %5.2f, %5.2f, %5.2f\n",/**/
"-- %s --\n"
"%5.0f, %5.0f, %5.0f, %5.0f, %5.0f, %5.0f, %5.0f, %5.0f, %5.0f, %5.0f, %5.0f, %5.0f, %5.0f, %5.0f, %5.0f, %5.0f\n",
name.c_str (),
m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44 );
}
};
inline void matrix_set_highlevel ( Matrix & ret,
float m11, float m12, float m13, float m14,
float m21, float m22, float m23, float m24,
float m31, float m32, float m33, float m34,
float m41, float m42, float m43, float m44 ) noexcept
{
/**/ret.m11 = m11; ret.m12 = m12; ret.m13 = m13; ret.m14 = m14;
ret.m21 = m21; ret.m22 = m22; ret.m23 = m23; ret.m24 = m24;
ret.m31 = m31; ret.m32 = m32; ret.m33 = m33; ret.m34 = m34;
ret.m41 = m41; ret.m42 = m42; ret.m43 = m43; ret.m44 = m44;/**/
/*memcpy ( ret.arr, &m11, sizeof ( float ) * 16 );/**/
}
inline void matrix_set_sse ( Matrix & ret,
float m11, float m12, float m13, float m14,
float m21, float m22, float m23, float m24,
float m31, float m32, float m33, float m34,
float m41, float m42, float m43, float m44 ) noexcept
{
ret.sse [ 0 ] = _mm_setr_ps ( m11, m12, m13, m14 );
ret.sse [ 1 ] = _mm_setr_ps ( m21, m22, m23, m24 );
ret.sse [ 2 ] = _mm_setr_ps ( m31, m32, m33, m34 );
ret.sse [ 3 ] = _mm_setr_ps ( m41, m42, m43, m44 );
}
inline void matrix_set_avx256 ( Matrix & ret,
float m11, float m12, float m13, float m14,
float m21, float m22, float m23, float m24,
float m31, float m32, float m33, float m34,
float m41, float m42, float m43, float m44 ) noexcept
{
ret.avx [ 0 ] = _mm256_setr_ps ( m11, m12, m13, m14, m21, m22, m23, m24 );
ret.avx [ 1 ] = _mm256_setr_ps ( m31, m32, m33, m34, m41, m42, m43, m44 );
}
inline void matrix_multiply_highlevel ( Matrix & ret, const Matrix & m1, const Matrix & m2 ) noexcept
{
ret.m11 = ( ( ( m1.m11 * m2.m11 ) + ( m1.m12 * m2.m21 ) ) + ( m1.m13 * m2.m31 ) ) + ( m1.m14 * m2.m41 );
ret.m12 = ( ( ( m1.m11 * m2.m12 ) + ( m1.m12 * m2.m22 ) ) + ( m1.m13 * m2.m32 ) ) + ( m1.m14 * m2.m42 );
ret.m13 = ( ( ( m1.m11 * m2.m13 ) + ( m1.m12 * m2.m23 ) ) + ( m1.m13 * m2.m33 ) ) + ( m1.m14 * m2.m43 );
ret.m14 = ( ( ( m1.m11 * m2.m14 ) + ( m1.m12 * m2.m24 ) ) + ( m1.m13 * m2.m34 ) ) + ( m1.m14 * m2.m44 );
ret.m21 = ( ( ( m1.m21 * m2.m11 ) + ( m1.m22 * m2.m21 ) ) + ( m1.m23 * m2.m31 ) ) + ( m1.m24 * m2.m41 );
ret.m22 = ( ( ( m1.m21 * m2.m12 ) + ( m1.m22 * m2.m22 ) ) + ( m1.m23 * m2.m32 ) ) + ( m1.m24 * m2.m42 );
ret.m23 = ( ( ( m1.m21 * m2.m13 ) + ( m1.m22 * m2.m23 ) ) + ( m1.m23 * m2.m33 ) ) + ( m1.m24 * m2.m43 );
ret.m24 = ( ( ( m1.m21 * m2.m14 ) + ( m1.m22 * m2.m24 ) ) + ( m1.m23 * m2.m34 ) ) + ( m1.m24 * m2.m44 );
ret.m31 = ( ( ( m1.m31 * m2.m11 ) + ( m1.m32 * m2.m21 ) ) + ( m1.m33 * m2.m31 ) ) + ( m1.m34 * m2.m41 );
ret.m32 = ( ( ( m1.m31 * m2.m12 ) + ( m1.m32 * m2.m22 ) ) + ( m1.m33 * m2.m32 ) ) + ( m1.m34 * m2.m42 );
ret.m33 = ( ( ( m1.m31 * m2.m13 ) + ( m1.m32 * m2.m23 ) ) + ( m1.m33 * m2.m33 ) ) + ( m1.m34 * m2.m43 );
ret.m34 = ( ( ( m1.m31 * m2.m14 ) + ( m1.m32 * m2.m24 ) ) + ( m1.m33 * m2.m34 ) ) + ( m1.m34 * m2.m44 );
ret.m41 = ( ( ( m1.m41 * m2.m11 ) + ( m1.m42 * m2.m21 ) ) + ( m1.m43 * m2.m31 ) ) + ( m1.m44 * m2.m41 );
ret.m42 = ( ( ( m1.m41 * m2.m12 ) + ( m1.m42 * m2.m22 ) ) + ( m1.m43 * m2.m32 ) ) + ( m1.m44 * m2.m42 );
ret.m43 = ( ( ( m1.m41 * m2.m13 ) + ( m1.m42 * m2.m23 ) ) + ( m1.m43 * m2.m33 ) ) + ( m1.m44 * m2.m43 );
ret.m44 = ( ( ( m1.m41 * m2.m14 ) + ( m1.m42 * m2.m24 ) ) + ( m1.m43 * m2.m34 ) ) + ( m1.m44 * m2.m44 );
}
inline void matrix_multiply_highlevel_parallel ( Matrix & ret, const Matrix & m1, const Matrix & m2 ) noexcept
{
#pragma omp parallel for
for ( int y = 0; y < 4; ++y )
{
for ( int x = 0; x < 4; ++x )
{
ret.arr [ y * 4 + x ] =
( m1.arr [ y * 4 + 0 ] * m2.arr [ 0 * 4 + x ] ) +
( m1.arr [ y * 4 + 1 ] * m2.arr [ 1 * 4 + x ] ) +
( m1.arr [ y * 4 + 2 ] * m2.arr [ 2 * 4 + x ] ) +
( m1.arr [ y * 4 + 3 ] * m2.arr [ 3 * 4 + x ] );
}
}
}
inline void matrix_multiply_sse ( Matrix & ret, const Matrix & m1, const Matrix & m2 ) noexcept
{
ret.sse [ 0 ] = _mm_add_ps ( _mm_add_ps ( _mm_add_ps (
_mm_mul_ps ( _mm_shuffle_ps ( m1.sse [ 0 ], m1.sse [ 0 ], 0x00 ), m2.sse [ 0 ] ),
_mm_mul_ps ( _mm_shuffle_ps ( m1.sse [ 0 ], m1.sse [ 0 ], 0x55 ), m2.sse [ 1 ] ) ),
_mm_mul_ps ( _mm_shuffle_ps ( m1.sse [ 0 ], m1.sse [ 0 ], 0xaa ), m2.sse [ 2 ] ) ),
_mm_mul_ps ( _mm_shuffle_ps ( m1.sse [ 0 ], m1.sse [ 0 ], 0xff ), m2.sse [ 3 ] ) );
ret.sse [ 1 ] = _mm_add_ps ( _mm_add_ps ( _mm_add_ps (
_mm_mul_ps ( _mm_shuffle_ps ( m1.sse [ 1 ], m1.sse [ 1 ], 0x00 ), m2.sse [ 0 ] ),
_mm_mul_ps ( _mm_shuffle_ps ( m1.sse [ 1 ], m1.sse [ 1 ], 0x55 ), m2.sse [ 1 ] ) ),
_mm_mul_ps ( _mm_shuffle_ps ( m1.sse [ 1 ], m1.sse [ 1 ], 0xaa ), m2.sse [ 2 ] ) ),
_mm_mul_ps ( _mm_shuffle_ps ( m1.sse [ 1 ], m1.sse [ 1 ], 0xff ), m2.sse [ 3 ] ) );
ret.sse [ 2 ] = _mm_add_ps ( _mm_add_ps ( _mm_add_ps (
_mm_mul_ps ( _mm_shuffle_ps ( m1.sse [ 2 ], m1.sse [ 2 ], 0x00 ), m2.sse [ 0 ] ),
_mm_mul_ps ( _mm_shuffle_ps ( m1.sse [ 2 ], m1.sse [ 2 ], 0x55 ), m2.sse [ 1 ] ) ),
_mm_mul_ps ( _mm_shuffle_ps ( m1.sse [ 2 ], m1.sse [ 2 ], 0xaa ), m2.sse [ 2 ] ) ),
_mm_mul_ps ( _mm_shuffle_ps ( m1.sse [ 2 ], m1.sse [ 2 ], 0xff ), m2.sse [ 3 ] ) );
ret.sse [ 3 ] = _mm_add_ps ( _mm_add_ps ( _mm_add_ps (
_mm_mul_ps ( _mm_shuffle_ps ( m1.sse [ 3 ], m1.sse [ 3 ], 0x00 ), m2.sse [ 0 ] ),
_mm_mul_ps ( _mm_shuffle_ps ( m1.sse [ 3 ], m1.sse [ 3 ], 0x55 ), m2.sse [ 1 ] ) ),
_mm_mul_ps ( _mm_shuffle_ps ( m1.sse [ 3 ], m1.sse [ 3 ], 0xaa ), m2.sse [ 2 ] ) ),
_mm_mul_ps ( _mm_shuffle_ps ( m1.sse [ 3 ], m1.sse [ 3 ], 0xff ), m2.sse [ 3 ] ) );
}
inline void matrix_multiply_sse_with_fma3 ( Matrix & ret, const Matrix & m1, const Matrix & m2 ) noexcept
{
ret.sse [ 0 ] =
_mm_fmadd_ps ( _mm_shuffle_ps ( m1.sse [ 0 ], m1.sse [ 0 ], 0x00 ), m2.sse [ 0 ],
_mm_fmadd_ps ( _mm_shuffle_ps ( m1.sse [ 0 ], m1.sse [ 0 ], 0x55 ), m2.sse [ 1 ],
_mm_fmadd_ps ( _mm_shuffle_ps ( m1.sse [ 0 ], m1.sse [ 0 ], 0xaa ), m2.sse [ 2 ],
_mm_mul_ps ( _mm_shuffle_ps ( m1.sse [ 0 ], m1.sse [ 0 ], 0xff ), m2.sse [ 3 ] ) ) ) );
ret.sse [ 1 ] =
_mm_fmadd_ps ( _mm_shuffle_ps ( m1.sse [ 1 ], m1.sse [ 1 ], 0x00 ), m2.sse [ 0 ],
_mm_fmadd_ps ( _mm_shuffle_ps ( m1.sse [ 1 ], m1.sse [ 1 ], 0x55 ), m2.sse [ 1 ],
_mm_fmadd_ps ( _mm_shuffle_ps ( m1.sse [ 1 ], m1.sse [ 1 ], 0xaa ), m2.sse [ 2 ],
_mm_mul_ps ( _mm_shuffle_ps ( m1.sse [ 1 ], m1.sse [ 1 ], 0xff ), m2.sse [ 3 ] ) ) ) );
ret.sse [ 2 ] =
_mm_fmadd_ps ( _mm_shuffle_ps ( m1.sse [ 2 ], m1.sse [ 2 ], 0x00 ), m2.sse [ 0 ],
_mm_fmadd_ps ( _mm_shuffle_ps ( m1.sse [ 2 ], m1.sse [ 2 ], 0x55 ), m2.sse [ 1 ],
_mm_fmadd_ps ( _mm_shuffle_ps ( m1.sse [ 2 ], m1.sse [ 2 ], 0xaa ), m2.sse [ 2 ],
_mm_mul_ps ( _mm_shuffle_ps ( m1.sse [ 2 ], m1.sse [ 2 ], 0xff ), m2.sse [ 3 ] ) ) ) );
ret.sse [ 3 ] =
_mm_fmadd_ps ( _mm_shuffle_ps ( m1.sse [ 3 ], m1.sse [ 3 ], 0x00 ), m2.sse [ 0 ],
_mm_fmadd_ps ( _mm_shuffle_ps ( m1.sse [ 3 ], m1.sse [ 3 ], 0x55 ), m2.sse [ 1 ],
_mm_fmadd_ps ( _mm_shuffle_ps ( m1.sse [ 3 ], m1.sse [ 3 ], 0xaa ), m2.sse [ 2 ],
_mm_mul_ps ( _mm_shuffle_ps ( m1.sse [ 3 ], m1.sse [ 3 ], 0xff ), m2.sse [ 3 ] ) ) ) );
}
inline void matrix_multiply_avx_4wide ( Matrix & ret, const Matrix & m1, const Matrix & m2 ) noexcept
{
ret.sse [ 0 ] = _mm_add_ps ( _mm_add_ps ( _mm_add_ps (
_mm_mul_ps ( _mm_broadcast_ss ( &m1.m11 ), m2.sse [ 0 ] ),
_mm_mul_ps ( _mm_broadcast_ss ( &m1.m12 ), m2.sse [ 1 ] ) ),
_mm_mul_ps ( _mm_broadcast_ss ( &m1.m13 ), m2.sse [ 2 ] ) ),
_mm_mul_ps ( _mm_broadcast_ss ( &m1.m14 ), m2.sse [ 3 ] ) );
ret.sse [ 1 ] = _mm_add_ps ( _mm_add_ps ( _mm_add_ps (
_mm_mul_ps ( _mm_broadcast_ss ( &m1.m21 ), m2.sse [ 0 ] ),
_mm_mul_ps ( _mm_broadcast_ss ( &m1.m22 ), m2.sse [ 1 ] ) ),
_mm_mul_ps ( _mm_broadcast_ss ( &m1.m23 ), m2.sse [ 2 ] ) ),
_mm_mul_ps ( _mm_broadcast_ss ( &m1.m24 ), m2.sse [ 3 ] ) );
ret.sse [ 2 ] = _mm_add_ps ( _mm_add_ps ( _mm_add_ps (
_mm_mul_ps ( _mm_broadcast_ss ( &m1.m31 ), m2.sse [ 0 ] ),
_mm_mul_ps ( _mm_broadcast_ss ( &m1.m32 ), m2.sse [ 1 ] ) ),
_mm_mul_ps ( _mm_broadcast_ss ( &m1.m33 ), m2.sse [ 2 ] ) ),
_mm_mul_ps ( _mm_broadcast_ss ( &m1.m34 ), m2.sse [ 3 ] ) );
ret.sse [ 3 ] = _mm_add_ps ( _mm_add_ps ( _mm_add_ps (
_mm_mul_ps ( _mm_broadcast_ss ( &m1.m41 ), m2.sse [ 0 ] ),
_mm_mul_ps ( _mm_broadcast_ss ( &m1.m42 ), m2.sse [ 1 ] ) ),
_mm_mul_ps ( _mm_broadcast_ss ( &m1.m43 ), m2.sse [ 2 ] ) ),
_mm_mul_ps ( _mm_broadcast_ss ( &m1.m44 ), m2.sse [ 3 ] ) );
}
inline void matrix_multiply_avx_4wide_with_fma3 ( Matrix & ret, const Matrix & m1, const Matrix & m2 ) noexcept
{
ret.sse [ 0 ] =
_mm_fmadd_ps ( _mm_broadcast_ss ( &m1.m11 ), m2.sse [ 0 ],
_mm_fmadd_ps ( _mm_broadcast_ss ( &m1.m12 ), m2.sse [ 1 ],
_mm_fmadd_ps ( _mm_broadcast_ss ( &m1.m13 ), m2.sse [ 2 ],
_mm_mul_ps ( _mm_broadcast_ss ( &m1.m14 ), m2.sse [ 3 ] ) ) ) );
ret.sse [ 1 ] =
_mm_fmadd_ps ( _mm_broadcast_ss ( &m1.m21 ), m2.sse [ 0 ],
_mm_fmadd_ps ( _mm_broadcast_ss ( &m1.m22 ), m2.sse [ 1 ],
_mm_fmadd_ps ( _mm_broadcast_ss ( &m1.m23 ), m2.sse [ 2 ],
_mm_mul_ps ( _mm_broadcast_ss ( &m1.m24 ), m2.sse [ 3 ] ) ) ) );
ret.sse [ 2 ] =
_mm_fmadd_ps ( _mm_broadcast_ss ( &m1.m31 ), m2.sse [ 0 ],
_mm_fmadd_ps ( _mm_broadcast_ss ( &m1.m32 ), m2.sse [ 1 ],
_mm_fmadd_ps ( _mm_broadcast_ss ( &m1.m33 ), m2.sse [ 2 ],
_mm_mul_ps ( _mm_broadcast_ss ( &m1.m34 ), m2.sse [ 3 ] ) ) ) );
ret.sse [ 3 ] =
_mm_fmadd_ps ( _mm_broadcast_ss ( &m1.m41 ), m2.sse [ 0 ],
_mm_fmadd_ps ( _mm_broadcast_ss ( &m1.m42 ), m2.sse [ 1 ],
_mm_fmadd_ps ( _mm_broadcast_ss ( &m1.m43 ), m2.sse [ 2 ],
_mm_mul_ps ( _mm_broadcast_ss ( &m1.m44 ), m2.sse [ 3 ] ) ) ) );
}
inline void matrix_multiply_avx256 ( Matrix & ret, const Matrix & m1, const Matrix & m2 ) noexcept
{
ret.avx [ 0 ] =_mm256_add_ps ( _mm256_add_ps ( _mm256_add_ps (
_mm256_mul_ps ( _mm256_shuffle_ps ( m1.avx [ 0 ], m1.avx [ 0 ], 0x00 ), _mm256_broadcast_ps ( &m2.sse [ 0 ] ) ),
_mm256_mul_ps ( _mm256_shuffle_ps ( m1.avx [ 0 ], m1.avx [ 0 ], 0x55 ), _mm256_broadcast_ps ( &m2.sse [ 1 ] ) ) ),
_mm256_mul_ps ( _mm256_shuffle_ps ( m1.avx [ 0 ], m1.avx [ 0 ], 0xaa ), _mm256_broadcast_ps ( &m2.sse [ 2 ] ) ) ),
_mm256_mul_ps ( _mm256_shuffle_ps ( m1.avx [ 0 ], m1.avx [ 0 ], 0xff ), _mm256_broadcast_ps ( &m2.sse [ 3 ] ) ) );
ret.avx [ 1 ] = _mm256_add_ps ( _mm256_add_ps ( _mm256_add_ps (
_mm256_mul_ps ( _mm256_shuffle_ps ( m1.avx [ 1 ], m1.avx [ 1 ], 0x00 ), _mm256_broadcast_ps ( &m2.sse [ 0 ] ) ),
_mm256_mul_ps ( _mm256_shuffle_ps ( m1.avx [ 1 ], m1.avx [ 1 ], 0x55 ), _mm256_broadcast_ps ( &m2.sse [ 1 ] ) ) ),
_mm256_mul_ps ( _mm256_shuffle_ps ( m1.avx [ 1 ], m1.avx [ 1 ], 0xaa ), _mm256_broadcast_ps ( &m2.sse [ 2 ] ) ) ),
_mm256_mul_ps ( _mm256_shuffle_ps ( m1.avx [ 1 ], m1.avx [ 1 ], 0xff ), _mm256_broadcast_ps ( &m2.sse [ 3 ] ) ) );
}
inline void matrix_multiply_avx256_with_fma3 ( Matrix & ret, const Matrix & m1, const Matrix & m2 ) noexcept
{
ret.avx [ 0 ] =
_mm256_fmadd_ps ( _mm256_shuffle_ps ( m1.avx [ 0 ], m1.avx [ 0 ], 0x00 ), _mm256_broadcast_ps ( &m2.sse [ 0 ] ),
_mm256_fmadd_ps ( _mm256_shuffle_ps ( m1.avx [ 0 ], m1.avx [ 0 ], 0x55 ), _mm256_broadcast_ps ( &m2.sse [ 1 ] ),
_mm256_fmadd_ps ( _mm256_shuffle_ps ( m1.avx [ 0 ], m1.avx [ 0 ], 0xaa ), _mm256_broadcast_ps ( &m2.sse [ 2 ] ),
_mm256_mul_ps ( _mm256_shuffle_ps ( m1.avx [ 0 ], m1.avx [ 0 ], 0xff ), _mm256_broadcast_ps ( &m2.sse [ 3 ] ) ) ) ) );
ret.avx [ 1 ] =
_mm256_fmadd_ps ( _mm256_shuffle_ps ( m1.avx [ 1 ], m1.avx [ 1 ], 0x00 ), _mm256_broadcast_ps ( &m2.sse [ 0 ] ),
_mm256_fmadd_ps ( _mm256_shuffle_ps ( m1.avx [ 1 ], m1.avx [ 1 ], 0x55 ), _mm256_broadcast_ps ( &m2.sse [ 1 ] ),
_mm256_fmadd_ps ( _mm256_shuffle_ps ( m1.avx [ 1 ], m1.avx [ 1 ], 0xaa ), _mm256_broadcast_ps ( &m2.sse [ 2 ] ),
_mm256_mul_ps ( _mm256_shuffle_ps ( m1.avx [ 1 ], m1.avx [ 1 ], 0xff ), _mm256_broadcast_ps ( &m2.sse [ 3 ] ) ) ) ) );
}
using matrix_set = std::function<void ( Matrix&, float, float, float, float, float, float, float, float, float, float, float, float, float, float, float, float )>;
using matrix_multiply = std::function<void ( Matrix &, const Matrix &, const Matrix & )>;
const struct TestCase
{
std::string name;
matrix_set set;
matrix_multiply multiply;
} testcases [] = {
{
std::string ( "High-Level Language(C++)" ),
matrix_set_highlevel,
matrix_multiply_highlevel
},
{
std::string ( "High-Level Language(C++) with OpenMP" ),
matrix_set_highlevel,
matrix_multiply_highlevel_parallel
},
{
std::string ( "SSE 2" ),
matrix_set_sse,
matrix_multiply_sse
},
{
std::string ( "SSE 2 with FMA3" ),
matrix_set_sse,
matrix_multiply_sse_with_fma3
},
{
std::string ( "AVX SSE Extended" ),
matrix_set_sse,
matrix_multiply_avx_4wide
},
{
std::string ( "AVX SSE Extended with FMA3" ),
matrix_set_sse,
matrix_multiply_avx_4wide_with_fma3
},
{
std::string ( "AVX-256" ),
matrix_set_avx256,
matrix_multiply_avx256
},
{
std::string ( "AVX-256 with FMA3" ),
matrix_set_avx256,
matrix_multiply_avx256_with_fma3
}
};
#define TEST_COUNT 1000000
inline void do_testcase_inline_highlevel () noexcept
{
printf ( "===== High-Level Language(C++) Inline Function =====\n" );
Matrix ret, m1, m2;
_mm_pause ();
uint64_t cycle = getCPUCycle ();
matrix_set_highlevel ( m1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 );
printf ( "Inline Set CPU Cycle: %lld\n", getCPUCycle () - cycle );
_mm_pause ();
double time = getCurrentTime ();
for ( int i = 0; i < TEST_COUNT; ++i )
matrix_set_highlevel ( m1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 );
printf ( "Inline Set Run Time: %lf\n", getCurrentTime () - time );
_mm_pause ();
matrix_set_highlevel ( m1, 11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34, 41, 42, 43, 44 );
matrix_set_highlevel ( m2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 );
_mm_pause ();
cycle = getCPUCycle ();
matrix_multiply_highlevel ( ret, m1, m2 );
printf ( "Inline Multiply CPU Cycle: %lld\n", getCPUCycle () - cycle );
_mm_pause ();
time = getCurrentTime ();
for ( int i = 0; i < TEST_COUNT; ++i )
matrix_multiply_highlevel ( ret, m1, m2 );
printf ( "Inline Multiply Run Time: %lf\n", getCurrentTime () - time );
_mm_pause ();
//ret.print ( std::string ( "Result" ) );
printf ( "\n" );
}
inline void do_testcase_inline_sse () noexcept
{
printf ( "===== SSE 2 Inline Function =====\n" );
Matrix ret, m1, m2;
_mm_pause ();
uint64_t cycle = getCPUCycle ();
matrix_set_sse ( m1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 );
printf ( "Inline SSE Set CPU Cycle: %lld\n", getCPUCycle () - cycle );
_mm_pause ();
double time = getCurrentTime ();
for ( int i = 0; i < TEST_COUNT; ++i )
matrix_set_sse ( m1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 );
printf ( "Inline SSE Set Run Time: %lf\n", getCurrentTime () - time );
_mm_pause ();
matrix_set_sse ( m1, 11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34, 41, 42, 43, 44 );
matrix_set_sse ( m2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 );
_mm_pause ();
cycle = getCPUCycle ();
matrix_multiply_sse ( ret, m1, m2 );
printf ( "Inline SSE Multiply CPU Cycle: %lld\n", getCPUCycle () - cycle );
_mm_pause ();
time = getCurrentTime ();
for ( int i = 0; i < TEST_COUNT; ++i )
matrix_multiply_sse ( ret, m1, m2 );
printf ( "Inline SSE Multiply Run Time: %lf\n", getCurrentTime () - time );
_mm_pause ();
//ret.print ( std::string ( "Result" ) );
printf ( "\n" );
}
inline void do_testcase ( const TestCase & testcase ) noexcept
{
printf ( "===== %s =====\n", testcase.name.c_str () );
Matrix ret, m1, m2;
_mm_pause ();
uint64_t cycle = getCPUCycle ();
testcase.set ( m1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 );
printf ( "%s Set CPU Cycle: %lld\n", testcase.name.c_str (), getCPUCycle () - cycle );
_mm_pause ();
double time = getCurrentTime ();
for ( int i = 0; i < TEST_COUNT; ++i )
testcase.set ( m1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 );
printf ( "%s Set Run Time: %lf\n", testcase.name.c_str (), getCurrentTime () - time );
_mm_pause ();
testcase.set ( m1, 11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34, 41, 42, 43, 44 );
testcase.set ( m2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 );
_mm_pause ();
cycle = getCPUCycle ();
testcase.multiply ( ret, m1, m2 );
printf ( "%s Multiply CPU Cycle: %lld\n", testcase.name.c_str (), getCPUCycle () - cycle );
_mm_pause ();
time = getCurrentTime ();
for ( int i = 0; i < TEST_COUNT; ++i )
testcase.multiply ( ret, m1, m2 );
printf ( "%s Multiply Run Time: %lf\n", testcase.name.c_str (), getCurrentTime () - time );
_mm_pause ();
//ret.print ( std::string ( "Result" ) );
printf ( "\n" );
}
int main ( void ) noexcept
{
BOOL priority = SetThreadPriority ( GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL );
DWORD_PTR setmask = SetThreadAffinityMask ( GetCurrentThread (), 1 );
printf ( "Setting Thread Priority: %d\nSetting Thread Affinity Mask: %lld\n\n", priority, setmask );
do_testcase_inline_highlevel ();
do_testcase_inline_sse ();
for ( auto testcase : testcases )
do_testcase ( testcase );
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment