Skip to content

Instantly share code, notes, and snippets.

@Mischa-Alff
Created October 31, 2014 12:58
Show Gist options
  • Save Mischa-Alff/18d4b483fa1bafeed3f4 to your computer and use it in GitHub Desktop.
Save Mischa-Alff/18d4b483fa1bafeed3f4 to your computer and use it in GitHub Desktop.
/*
g++
std::pow: Times (min, max, avg): 27635604us, 28006757us, 27696884us
expanded: Times (min, max, avg): 1318329us, 1409901us, 1335821us
jplatte's... thing: Times (min, max, avg): 7105522us, 7219386us, 7135305us
g++ -O3
std::pow: Times (min, max, avg): 25542284us, 26192220us, 25633656us
expanded: Times (min, max, avg): 0us, 0us, 0us
jplattes: Times (min, max, avg): 0us, 0us, 0us
g++ -march=native -mfpmath=sse
std::pow: Times (min, max, avg): 27970683us, 28704077us, 28318835us
expanded: Times (min, max, avg): 1759466us, 1768054us, 1763194us
jplatte : Times (min, max, avg): 5638495us, 6027941us, 5829464us
*/
#include <cmath>
#include <chrono>
#include <iostream>
template <typename baseType, unsigned exp>
struct intpow
{
constexpr baseType operator()(baseType base) const
{ return base * intpow<baseType, exp-1>()(base); }
};
template <typename baseType>
struct intpow<baseType, 1>
{
constexpr baseType operator()(baseType base) const
{ return base; }
};
template <typename baseType>
struct intpow<baseType, 0>
{
constexpr baseType operator()(baseType) const
{ return 1; }
};
int main()
{
int iterations = 100000000;
uint64_t min(-1), max(0), avg(0);
int steps = 10;
for(int n=0; n < steps; ++n)
{
auto start = std::chrono::high_resolution_clock::now();
for(unsigned int i=0; i < iterations; ++i)
{
float a=i;
float s=a/2.f;
float t=s/2.f;
float e=t/2.f;
float r=e/2.f;
float m=0.f;
m += std::pow(a, 4);
m += std::pow(s, 4);
m += std::pow(t, 4);
m += std::pow(e, 4);
m += std::pow(r, 4);
}
auto end = std::chrono::high_resolution_clock::now();
uint64_t current = std::chrono::duration_cast<std::chrono::microseconds>(end-start).count();
min = std::min(current, min);
max = std::max(current, max);
avg += current;
}
avg /= steps;
std::cout<<"std::pow: Times (min, max, avg): "<<min<<"us, "<<max<<"us, "<<avg<<"us"<<std::endl;
min=-1;max=avg=0;
for(int n=0; n < steps; ++n)
{
auto start = std::chrono::high_resolution_clock::now();
for(unsigned int i=0; i < iterations; ++i)
{
float a=i;
float s=a/2.f;
float t=s/2.f;
float e=t/2.f;
float r=e/2.f;
float m=0.f;
m += a*a*a*a;
m += s*s*s*s;
m += t*t*t*t;
m += e*e*e*e;
m += r*r*r*r;
}
auto end = std::chrono::high_resolution_clock::now();
uint64_t current = std::chrono::duration_cast<std::chrono::microseconds>(end-start).count();
min = std::min(current, min);
max = std::max(current, max);
avg += current;
}
avg /= steps;
std::cout<<"expanded: Times (min, max, avg): "<<min<<"us, "<<max<<"us, "<<avg<<"us"<<std::endl;
min=-1;max=avg=0;
for(int n=0; n < steps; ++n)
{
auto start = std::chrono::high_resolution_clock::now();
for(unsigned int i=0; i < iterations; ++i)
{
float a=i;
float s=a/2.f;
float t=s/2.f;
float e=t/2.f;
float r=e/2.f;
intpow<float, 4> jplatte;
float m=0.f;
m += jplatte(a);
m += jplatte(s);
m += jplatte(t);
m += jplatte(e);
m += jplatte(r);
}
auto end = std::chrono::high_resolution_clock::now();
uint64_t current = std::chrono::duration_cast<std::chrono::microseconds>(end-start).count();
min = std::min(current, min);
max = std::max(current, max);
avg += current;
}
avg /= steps;
std::cout<<"jplattes: Times (min, max, avg): "<<min<<"us, "<<max<<"us, "<<avg<<"us"<<std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment