Skip to content

Instantly share code, notes, and snippets.

@Borgleader
Created January 23, 2015 00:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Borgleader/38e3b17b5489a7b3de08 to your computer and use it in GitHub Desktop.
Save Borgleader/38e3b17b5489a7b3de08 to your computer and use it in GitHub Desktop.
// 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