Last active
March 12, 2020 10:35
-
-
Save r1walz/9cff69b334e539b03e3d0b2558bfd224 to your computer and use it in GitHub Desktop.
A simple program crafted using the power of SIMD programming: $ g++ -O0 simd.cpp -o main && ./main
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cmath> | |
#include <cfloat> | |
#include <iostream> | |
#include <xmmintrin.h> | |
#define start_routine() int begtime = clock(); | |
#define end_routine() do { \ | |
int endtime = clock(); \ | |
std::cerr << "\n" << "Time elapsed: " \ | |
<< (endtime - begtime) * 1000 / CLOCKS_PER_SEC \ | |
<< " ms\n\n"; \ | |
} while (0); | |
#define ARRAY_SIZE 100000000 | |
float m_fResultArray[ARRAY_SIZE]; | |
float m_fInitialArray[ARRAY_SIZE]; | |
float m_fMin, m_fMax; | |
void init() { | |
m_fMin = FLT_MAX; | |
m_fMax = FLT_MIN; | |
for (int i = 0; i < ARRAY_SIZE; ++i) | |
m_fInitialArray[i] = rand(); | |
} | |
void normal_call() { | |
for (int i = 0; i < ARRAY_SIZE; ++i) { | |
m_fResultArray[i] = std::sqrt(m_fInitialArray[i] * 2.8f); | |
if (m_fResultArray[i] < m_fMin) | |
m_fMin = m_fResultArray[i]; | |
if (m_fResultArray[i] > m_fMax) | |
m_fMax = m_fResultArray[i]; | |
} | |
} | |
void simd_call() { | |
__m128 coeff = _mm_set_ps1(2.8f); | |
__m128 tmp; | |
__m128 min128 = _mm_set_ps1(FLT_MAX); | |
__m128 max128 = _mm_set_ps1(FLT_MIN); | |
__m128 *pSource = (__m128 *)m_fInitialArray; | |
__m128 *pDest = (__m128 *)m_fResultArray; | |
for (int i = 0; i < ARRAY_SIZE / 4; ++i) { | |
tmp = _mm_mul_ps(*pSource, coeff); | |
*pDest = _mm_sqrt_ps(tmp); | |
min128 = _mm_min_ps(*pDest, min128); | |
max128 = _mm_max_ps(*pDest, max128); | |
++pSource, ++pDest; | |
} | |
union u { | |
__m128 m; | |
float f[4]; | |
} x; | |
x.m = min128; | |
m_fMin = std::min(x.f[0], std::min(x.f[1], std::min(x.f[2], x.f[3]))); | |
x.m = max128; | |
m_fMax = std::max(x.f[0], std::max(x.f[1], std::max(x.f[2], x.f[3]))); | |
} | |
int main() { | |
srand(time(NULL)); | |
init(); | |
{ | |
std::cout << "Normal Call:\n\n"; | |
start_routine(); | |
normal_call(); | |
std::cout << "Fmin: " << m_fMin << '\n' | |
<< "Fmax: " << m_fMax << std::endl; | |
end_routine(); | |
} | |
{ | |
std::cout << "------------------" | |
"\n\nSIMD Call:\n\n"; | |
start_routine(); | |
simd_call(); | |
std::cout << "Fmin: " << m_fMin << '\n' | |
<< "Fmax: " << m_fMax << std::endl; | |
end_routine(); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment