-
-
Save Borgleader/38e3b17b5489a7b3de08 to your computer and use it in GitHub Desktop.
Using nonius: https://github.com/rmartinho/nonius
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
// Average std::complex<float> : 3.73823E-08 | |
// Average struct { float, float } : 9.32318E-09 | |
// ~4x speed diff | |
#include <complex> | |
#include <random> | |
#include <vector> | |
#include <nonius/main.h++> | |
template <typename T> | |
std::vector<T> make_test_vector(size_t size) | |
{ | |
std::vector<T> vec(size); | |
std::random_device rd; | |
std::mt19937 gen(rd()); | |
std::uniform_real_distribution<float> dis(-1, 1); | |
for (auto& c : vec) { c = { dis(gen), dis(gen) }; } | |
return vec; | |
} | |
NONIUS_BENCHMARK("std::complex<float>", [](nonius::chronometer meter) | |
{ | |
typedef std::complex<float> complexf; | |
auto out0 = make_test_vector<complexf>(meter.runs()); | |
auto out1 = make_test_vector<complexf>(meter.runs()); | |
auto out2 = make_test_vector<complexf>(meter.runs()); | |
auto out3 = make_test_vector<complexf>(meter.runs()); | |
auto twiddle = make_test_vector<complexf>(meter.runs()); | |
meter.measure([&](int k) | |
{ | |
complexf Uk = out0[k]; | |
complexf Uk_N1 = out1[k]; | |
complexf w = twiddle[k]; | |
// Twiddle Zk, Z'k then butterfly | |
complexf Zk = w * out2[k]; | |
complexf Zpk = std::conj(w) * out3[k]; | |
complexf Zsum = Zk + Zpk; | |
complexf Zdif = complexf(0.0f, -1.0f) * (Zk - Zpk); | |
out0[k] = Uk + Zsum; | |
out1[k] = Uk_N1 + Zdif; | |
out2[k] = Uk - Zsum; | |
out3[k] = Uk_N1 - Zdif; | |
}); | |
}) | |
struct complexf_t { float re, im; }; | |
NONIUS_BENCHMARK("struct { float, float }", [](nonius::chronometer meter) | |
{ | |
typedef complexf_t complexf; | |
auto out0 = make_test_vector<complexf>(meter.runs()); | |
auto out1 = make_test_vector<complexf>(meter.runs()); | |
auto out2 = make_test_vector<complexf>(meter.runs()); | |
auto out3 = make_test_vector<complexf>(meter.runs()); | |
auto twiddle = make_test_vector<complexf>(meter.runs()); | |
meter.measure([&](int k) | |
{ | |
complexf const &w = twiddle[k]; | |
complexf const &in2 = out2[k]; | |
complexf const &in3 = out3[k]; | |
float Zkr = w.re*in2.re - w.im*in2.im; | |
float Zki = w.re*in2.im + w.im*in2.re; | |
float Zpkr = w.re*in3.re + w.im*in3.im; | |
float Zpki = w.re*in3.im - w.im*in3.re; | |
float Zsumr = Zkr + Zpkr; | |
float Zsumi = Zki + Zpki; | |
float Zdifr = Zki - Zpki; | |
float Zdifi = Zpkr - Zkr; | |
out2[k].re = out0[k].re - Zsumr; | |
out2[k].im = out0[k].im - Zsumi; | |
out0[k].re += Zsumr; | |
out0[k].im += Zsumi; | |
out3[k].re = out1[k].re - Zdifr; | |
out3[k].im = out1[k].im - Zdifi; | |
out1[k].re += Zdifr; | |
out1[k].im += Zdifi; | |
}); | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment