Skip to content

Instantly share code, notes, and snippets.

@OlegJakushkin
Created June 5, 2016 16:36
Show Gist options
  • Save OlegJakushkin/32d9ee2ceef13936be56c8dd6b6ac9d3 to your computer and use it in GitHub Desktop.
Save OlegJakushkin/32d9ee2ceef13936be56c8dd6b6ac9d3 to your computer and use it in GitHub Desktop.
#include <vector>
#include <algorithm>
#include <random>
#include <cmath>
#include <functional>
#include <iostream>
#include <benchmark/benchmark.h>
#include <numeric>
#include <blond/trackers/sin.h>
#include <gsl/gsl_sf_trig.h>
using namespace std;
static void BM_sin_default(benchmark::State& state) {
int data_size = state.range_x();
double lower_bound = 0;
double upper_bound = 1;
random_device device;
mt19937 engine(device());
uniform_real_distribution<double> distribution(lower_bound,upper_bound);
auto generator = bind(distribution, engine);
vector<double> data(data_size);
while (state.KeepRunning()) {
state.PauseTiming();
generate(begin(data), end(data), generator);
state.ResumeTiming();
#pragma omp parallel for
for(int i = 0; i < data_size; ++i) {
data[i] = sin(data[i]);
}
}
cout << accumulate(data.begin(), data.end(), 0) << endl;
}
BENCHMARK(BM_sin_default)->Arg(2147483647);
static void BM_sin_fast(benchmark::State& state) {
int data_size = state.range_x();
double lower_bound = 0;
double upper_bound = 1;
random_device device;
mt19937 engine(device());
uniform_real_distribution<double> distribution(lower_bound, upper_bound);
auto generator = bind(distribution, engine);
vector<double> data(data_size);
while (state.KeepRunning()) {
state.PauseTiming();
generate(begin(data), end(data), generator);
state.ResumeTiming();
#pragma omp parallel for
for(int i = 0; i < data_size; ++i) {
data[i] = blond::vdt::fast_sin(data[i]);
}
}
cout << accumulate(data.begin(), data.end(), 0) << endl;
}
BENCHMARK(BM_sin_fast)->Arg(2147483647);
static void BM_sin_gsl(benchmark::State& state) {
int data_size = state.range_x();
double lower_bound = 0;
double upper_bound = 1;
random_device device;
mt19937 engine(device());
uniform_real_distribution<double> distribution(lower_bound, upper_bound);
auto generator = bind(distribution, engine);
vector<double> data(data_size);
while (state.KeepRunning()) {
state.PauseTiming();
generate(begin(data), end(data), generator);
state.ResumeTiming();
#pragma omp parallel for
for(int i = 0; i < data_size; ++i) {
data[i] = gsl_sf_sin(data[i]);
}
}
cout << accumulate(data.begin(), data.end(), 0) << endl;
}
BENCHMARK(BM_sin_gsl)->Arg(2147483647);
BENCHMARK_MAIN();
#include <vector>
#include <algorithm>
#include <random>
#include <cmath>
#include <functional>
#include <iostream>
#include <numeric>
#include <blond/trackers/sin.h>
#include <gsl/gsl_sf_trig.h>
using namespace std;
template <typename T>
std::vector<T> operator-(const std::vector<T>& a, const std::vector<T>& b)
{
//assert(a.size() == b.size());
std::vector<T> result;
result.reserve(a.size());
std::transform(a.begin(), a.end(), b.begin(),
std::back_inserter(result), std::minus<T>());
return result;
}
template <typename T>
T mean(const std::vector<T>& a){
T sum = std::accumulate(a.begin(), a.end(), (T)0);
T mean = sum / a.size();
return mean;
}
int main() {
int data_size = 200000000;
double lower_bound = 0;
double upper_bound = 1;
random_device device;
mt19937 engine(device());
uniform_real_distribution<double> distribution(lower_bound,upper_bound);
auto generator = bind(distribution, engine);
vector<double> data(data_size);
generate(data.begin(), data.end(), generator);
vector<double> sin_double(data_size);
vector<double> sin_gsl(data_size);
vector<double> fast_sin_double(data_size);
double mean_error_sin_gsl = 0;
double mean_error_fast_sin = 0;
double max_error_sin_gsl = 0;
double max_error_fast_sin = 0;
for(int i = 0; i < data_size; ++i) {
sin_double[i] = sin(data[i]);
}
for(int i = 0; i < data_size; ++i) {
sin_gsl[i] = gsl_sf_sin(data[i]);
}
for(int i = 0; i < data_size; ++i) {
fast_sin_double[i] = blond::vdt::fast_sin(data[i]);
}
auto error_sin_gsl = sin_double - sin_gsl;
auto error_fast_sin = sin_double - fast_sin_double;
std::transform(error_sin_gsl.begin(), error_sin_gsl.end(), error_sin_gsl.begin(),[](double v){return fabs(v);} );
std::transform(error_fast_sin.begin(), error_fast_sin.end(), error_fast_sin.begin(), [](double v){return fabs(v);} );
max_error_sin_gsl = *( max_element(error_sin_gsl.begin(), error_sin_gsl.end()));
max_error_fast_sin = *( max_element(error_fast_sin.begin(), error_fast_sin.end()));
mean_error_sin_gsl = mean(error_sin_gsl);
mean_error_fast_sin = mean(error_fast_sin);
cout << std::boolalpha << "report (std::sin<double> was taken as refrence):"
<< endl << "fast_sin: " << "max_error == " << max_error_fast_sin << "; mean_error == " << mean_error_fast_sin
<< endl << "sin_gsl: " << "max_error == " << mean_error_sin_gsl<< "; mean_error == " << mean_error_sin_gsl
<< endl << "thus expression \"fast_sin max error is bigger than gsl_sin max error\" is " << (max_error_fast_sin > mean_error_sin_gsl)
<< endl << "for sin of " << data_size << " elements."<< endl;
return 0;
}
Benchmark Time CPU Iterations
---------------------------------------------------------------
0
0
0
BM_sin_default/2G 8033266544 ns 63660000000 ns 1
BM_sin_default/2G 8028728247 ns 63716000000 ns 1
BM_sin_default/2G 8061509609 ns 63952000000 ns 1
BM_sin_default/2G_mean 8041168133 ns 63776000000 ns 1
BM_sin_default/2G_stddev 14502431 ns 126533263 ns 0
0
0
0
BM_sin_fast/2G 3103728294 ns 24504000000 ns 1
BM_sin_fast/2G 3040362597 ns 24176000000 ns 1
BM_sin_fast/2G 3100034714 ns 24440000000 ns 1
BM_sin_fast/2G_mean 3081375202 ns 24373333333 ns 1
BM_sin_fast/2G_stddev 29039467 ns 141960871 ns 0
0
0
0
BM_sin_gsl/2G 26887903690 ns 212668000000 ns 1
BM_sin_gsl/2G 27063994169 ns 212380000000 ns 1
BM_sin_gsl/2G 26909221172 ns 212668000000 ns 1
BM_sin_gsl/2G_mean 26953706344 ns 212572000000 ns 1
BM_sin_gsl/2G_stddev 78469366 ns 135764502 ns 0
===================================================================
fast_sin: max_error == 2.22045e-16; mean_error == 1.04033e-17
sin_gsl: max_error == 1.55677e-17; mean_error == 1.55677e-17
thus expression "fast_sin max error is bigger than gsl_sin max error" is true
for sin of 200000000 elements.
# --std=c++11 -L../external/install/lib/ -L./ -I../external/install/include -I../include -lbenchmark -lpthread -lblond -lgsl -Ofast -ffast-math -fno-rtti -m64 -march=native -fopenmp
# Tested on Azure DS4 size VM, Ubuntu 12.04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment