Skip to content

Instantly share code, notes, and snippets.

@GoaLitiuM
Last active September 9, 2018 22:33
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 GoaLitiuM/27c9cc173493cf5dad5df0c6f20fa09d to your computer and use it in GitHub Desktop.
Save GoaLitiuM/27c9cc173493cf5dad5df0c6f20fa09d to your computer and use it in GitHub Desktop.
DSP Performance Test (D)
Windows 10, i7-2600k @ 4.3ghz
Visual Studio 2017 (15.7.6), DMD 2.082.0, LDC 1.11.0
Compiled to x64 Release (Platform target: x64 in C#)
C++ Release:
----
Library Sine Test:
4464.29 sines/smp (144000000 iterations) (sum = 1.67772e+07)
Polynomial Approximation Test:
9009.01 sines/smp (144000000 iterations) (sum = -1.34218e+08)
Array Test (2048 samples):
22222.2 sines/smp (144000000 iterations) (sum = 1.67772e+07)
Array Test (16M samples):
22556.4 sines/smp (144000000 iterations) (sum = 1.67772e+07)
C# Release:
----
Library Sine Test:
736.1963 sines/smp (144000000 iterations) (sum = -4.297268E-09, stopWatch time = 4075 ms)
Polynomial Approximation Test:
11363.64 sines/smp (144000000 iterations) (sum = -4.294967E+09, stopWatch time = 264 ms)
Array Test (2048 samples):
15544.04 sines/smp (144000000 iterations) (sum = -1.677722E+07, stopWatch time = 193 ms)
Array Test (16M samples):
15306.12 sines/smp (144000000 iterations) (sum = -1.677722E+07, stopWatch time = 196 ms)
D LDC Release:
----
Library Sine Test:
3671.97 sines/smp (144000000 iterations) (sum = 1.67772e+07)
Polynomial Approximation Test:
7125.89 sines/smp (144000000 iterations) (sum = -1.34218e+08)
Array Test (2048 samples):
19736.8 sines/smp (144000000 iterations) (sum = 1.67772e+07)
Array Test (16M samples):
19480.5 sines/smp (144000000 iterations) (sum = 1.67772e+07)
D DMD Release:
----
Library Sine Test:
826.902 sines/smp (144000000 iterations) (sum = 1.67772e+07)
Polynomial Approximation Test:
2288.33 sines/smp (144000000 iterations) (sum = -1.34218e+08)
Array Test (2048 samples):
3968.25 sines/smp (144000000 iterations) (sum = 1.67772e+07)
Array Test (16M samples):
3911.34 sines/smp (144000000 iterations) (sum = 1.67772e+07)
// C++ version ported to D from https://github.com/schmid/Unity-DSP-Performance-Test
module TestSineSpeedD;
import std.stdio;
import core.stdc.stdlib;
import std.algorithm;
static import std.math;
import std.math : PI;
import std.math : sin, fabs;
//import core.stdc.math : sin, fabs; // faster in some cases, but lets stay idiomatic
import std.conv;
const float M_2_PI = cast(float)std.math.M_2_PI;
const long ITERATIONS = 48000L * 3000L;
abstract class Test
{
public:
string name;
this(string name) { this.name = name; }
abstract void init();
abstract float perform_test(long iterations);
};
class Test_sinf : Test
{
public:
this(string name) { super(name); }
protected:
override void init() { }
override float perform_test(long iterations)
{
float sum = 0.0f;
float angle_per_iteration = M_2_PI / iterations;
for (long i = 0; i < iterations; ++i)
{
float angle = i * angle_per_iteration;
sum += sin(angle); // make sure that code isn't optimized away
}
return sum;
}
};
class Test_table : Test
{
public:
this(string name, int table_size) { super(name); this.table_size = table_size;}
protected:
override void init()
{
sine = new float[table_size];
float angle_per_iteration = M_2_PI / table_size;
for (int i = 0; i < table_size; ++i)
{
sine[i] = sin(i * angle_per_iteration);
}
}
override float perform_test(long iterations)
{
float sum = 0.0f;
const float periods_per_iteration = 0.9999f / iterations;
for (long i = 0; i < iterations; ++i)
{
float periods = i * periods_per_iteration;
int idx = cast(int)(periods * table_size);
sum += sine[idx];
}
return sum;
}
private:
int table_size = -1;
float[] sine;
};
class Test_parabolic : Test
{
public:
this(string name) { super(name); }
protected:
override void init() { }
// From Nicolas Capens: http://forum.devmaster.net/t/fast-and-accurate-sine-cosine/9648
// float sine(float x)
// {
// const float B = 4/pi;
// const float C = -4/(pi*pi);
// float y = B * x + C * x * abs(x);
// #ifdef EXTRA_PRECISION
// // const float Q = 0.775;
// const float P = 0.225;
// y = P * (y * abs(y) - y) + y; // Q * y + P * y * abs(y)
// #endif
// }
//
// So, for the inaccurate version we have:
// B = 4/pi
// C = -4/(pi*pi)
// y = B x + C x abs(x)
//
// We can use periods instead of degrees:
// p * 2 pi = x
// y = (4/pi) * x + (-4/(pi*pi)) * x * abs(x)
// = 4 / pi * x + -4 / pi * pi * x * abs(x)
// = 4 / pi * p * 2 * pi + -4 / pi * pi * p * 2 * pi * abs(p * 2 * pi)
// = 4 * p * 2 + -4 * p * 2 * pi * abs(p * 2 * pi)
// = 8 * p + -8 * pi * p * abs(p * 2 * pi)
// = 8p + -8pi * p * abs(p * 2pi)
override float perform_test(long iterations)
{
float sum = 0.0f;
const float periods_per_iteration = 1.0f / iterations;
const float F = -8.0f * PI;
for (long i = 0; i < iterations; ++i)
{
float p = i * periods_per_iteration;
float sine = 8 * p + F * p * fabs(p * M_2_PI);
sum += sine;
}
return sum;
}
};
void run(ref Test test, long iterations)
{
import std.datetime.stopwatch : benchmark, StopWatch, AutoStart;
test.init();
writeln(test.name, ":");
auto sw = StopWatch(AutoStart.no);
sw.start();
float result = test.perform_test(iterations);
sw.stop();
auto time_ms = sw.peek.total!"msecs";
float time_s = time_ms * 0.001f;
writeln(" ", (iterations/48000) / time_s, " sines/smp ("
, iterations, " iterations) (sum = ", result, ")");
}
int main()
{
Test_sinf test_sinf = new Test_sinf("Library Sine Test");
Test_parabolic test_parabolic = new Test_parabolic("Polynomial Approximation Test");
Test_table test_table_2048 = new Test_table("Array Test (2048 samples)", 2048);
//Test_table test_table_64K("table test (64K samples)", 1 << 16);
Test_table test_table_16M = new Test_table("Array Test (16M samples)", 1 << 24);
Test[] tests =
[
test_sinf, test_parabolic, test_table_2048, /*test_table_64K,*/ test_table_16M
];
foreach(ref Test test; tests)
{
run(test, ITERATIONS);
}
//cout << "done. (press 'any' key)" << endl;
//getch();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment