Created
June 5, 2016 16:36
-
-
Save OlegJakushkin/32d9ee2ceef13936be56c8dd6b6ac9d3 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 <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(); |
This file contains hidden or 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 <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; | |
} | |
This file contains hidden or 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
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