or for ldc http://docs.algorithm.dlang.io/latest/mir_math_common.html
On Sat, Apr 7, 2018 at 9:10 PM, Daniel Kozak <[email protected]> wrote: > can you try it with c math functions? > > instead of std.math, try to use core.stdc.math > > On Sat, Apr 7, 2018 at 8:53 PM, Arun Chandrasekaran via > Digitalmars-d-learn <[email protected]> wrote: > >> What am I doing wrong here that makes the D equivalent 2.5 times slower >> than it's C equivalent? >> >> Compilers used: >> >> LDC2: LDC - the LLVM D compiler (1.8.0) >> GCC: gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 >> >> 11:36:39 ~/code/c/test2$ ldc2 sigmoid.d -O5 && ./sigmoid >> Max deviation is 0.001664 >> 10^7 iterations using sigmoid1: 308 ms >> 10^7 iterations using sigmoid2: 30 ms >> 11:36:55 ~/code/c/test2 >> $ gcc sigmoid.c -o sigmoid-c -O3 -lm 2>/dev/null && ./sigmoid-c >> Max deviation is 0.001664 >> 10^7 iterations using sigmoid1: 134 ms >> 10^7 iterations using sigmoid2: 29 ms >> 11:37:10 ~/code/c/test2 >> $ >> >> C code, taken from https://stackoverflow.com/ques >> tions/412019/math-optimization-in-c-sharp#412176: >> >> ``` >> #include <math.h> >> #include <stdio.h> >> #include <time.h> >> >> #define SCALE 320.0f >> #define RESOLUTION 2047 >> #define MIN -RESOLUTION / SCALE >> #define MAX RESOLUTION / SCALE >> >> static float sigmoid_lut[RESOLUTION + 1]; >> >> void init_sigmoid_lut(void) { >> int i; >> for (i = 0; i < RESOLUTION + 1; i++) { >> sigmoid_lut[i] = (1.0 / (1.0 + exp(-i / SCALE))); >> } >> } >> >> static float sigmoid1(const float value) { >> return (1.0f / (1.0f + expf(-value))); >> } >> >> static float sigmoid2(const float value) { >> if (value <= MIN) return 0.0f; >> if (value >= MAX) return 1.0f; >> if (value >= 0) return sigmoid_lut[(int)(value * SCALE + 0.5f)]; >> return 1.0f-sigmoid_lut[(int)(-value * SCALE + 0.5f)]; >> } >> >> float test_error() { >> float x; >> float emax = 0.0; >> >> for (x = -10.0f; x < 10.0f; x+=0.00001f) { >> float v0 = sigmoid1(x); >> float v1 = sigmoid2(x); >> float error = fabsf(v1 - v0); >> if (error > emax) { emax = error; } >> } >> return emax; >> } >> >> int sigmoid1_perf() { >> clock_t t0, t1; >> int i; >> float x, y = 0.0f; >> >> t0 = clock(); >> for (i = 0; i < 10; i++) { >> for (x = -5.0f; x <= 5.0f; x+=0.00001f) { >> y = sigmoid1(x); >> } >> } >> t1 = clock(); >> printf("", y); /* To avoid sigmoidX() calls being optimized away */ >> return (t1 - t0) / (CLOCKS_PER_SEC / 1000); >> } >> >> int sigmoid2_perf() { >> clock_t t0, t1; >> int i; >> float x, y = 0.0f; >> t0 = clock(); >> for (i = 0; i < 10; i++) { >> for (x = -5.0f; x <= 5.0f; x+=0.00001f) { >> y = sigmoid2(x); >> } >> } >> t1 = clock(); >> printf("", y); /* To avoid sigmoidX() calls being optimized away */ >> return (t1 - t0) / (CLOCKS_PER_SEC / 1000); >> } >> >> int main(void) { >> init_sigmoid_lut(); >> printf("Max deviation is %0.6f\n", test_error()); >> printf("10^7 iterations using sigmoid1: %d ms\n", sigmoid1_perf()); >> printf("10^7 iterations using sigmoid2: %d ms\n", sigmoid2_perf()); >> >> return 0; >> } >> ``` >> >> D equivalent: >> >> ``` >> module sigmoid; >> >> import std.stdio; >> import std.math; >> import std.datetime.stopwatch; >> >> enum SCALE = 320.0f; >> enum RESOLUTION = 2047; >> enum MIN = -RESOLUTION / SCALE; >> enum MAX = RESOLUTION / SCALE; >> >> float[RESOLUTION + 1] sigmoid_lut; >> >> void init_sigmoid_lut() { >> int i; >> for (i = 0; i < RESOLUTION + 1; i++) { >> sigmoid_lut[i] = (1.0 / (1.0 + exp(-i / SCALE))); >> } >> } >> >> private float sigmoid1(const float value) { >> return (1.0f / (1.0f + exp(-value))); >> } >> >> private float sigmoid2(const float value) { >> if (value <= MIN) return 0.0f; >> if (value >= MAX) return 1.0f; >> if (value >= 0) return sigmoid_lut[cast(int)(value * SCALE + 0.5f)]; >> return 1.0f-sigmoid_lut[cast(int)(-value * SCALE + 0.5f)]; >> } >> >> private float test_error() { >> float x; >> float emax = 0.0; >> >> for (x = -10.0f; x < 10.0f; x+=0.00001f) { >> float v0 = sigmoid1(x); >> float v1 = sigmoid2(x); >> float error = fabs(v1 - v0); >> if (error > emax) { emax = error; } >> } >> return emax; >> } >> >> private auto sigmoid1_perf() { >> auto sw = StopWatch(AutoStart.yes); >> int i; >> float x, y = 0.0f; >> >> for (i = 0; i < 10; i++) { >> for (x = -5.0f; x <= 5.0f; x+=0.00001f) { >> y = sigmoid1(x); >> } >> } >> return sw.peek.total!"msecs"; >> } >> >> private auto sigmoid2_perf() { >> auto sw = StopWatch(AutoStart.yes); >> int i; >> float x, y = 0.0f; >> for (i = 0; i < 10; i++) { >> for (x = -5.0f; x <= 5.0f; x+=0.00001f) { >> y = sigmoid2(x); >> } >> } >> return sw.peek.total!"msecs"; >> } >> >> int main() { >> init_sigmoid_lut(); >> writefln("Max deviation is %0.6f", test_error()); >> writefln("10^7 iterations using sigmoid1: %s ms", sigmoid1_perf()); >> writefln("10^7 iterations using sigmoid2: %s ms", sigmoid2_perf()); >> >> return 0; >> } >> ``` >> > >
