Skip to content

Instantly share code, notes, and snippets.

@r1walz
Last active March 12, 2020 10:35
Show Gist options
  • Save r1walz/9cff69b334e539b03e3d0b2558bfd224 to your computer and use it in GitHub Desktop.
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
#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