Last active
September 9, 2018 22:33
-
-
Save GoaLitiuM/27c9cc173493cf5dad5df0c6f20fa09d to your computer and use it in GitHub Desktop.
DSP Performance Test (D)
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
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) |
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
// 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