Benchmarking sigmoid function between C and D

Daniel Kozak kozzi11 at gmail.com
Sat Apr 7 19:14:27 UTC 2018


or for ldc http://docs.algorithm.dlang.io/latest/mir_math_common.html

On Sat, Apr 7, 2018 at 9:10 PM, Daniel Kozak <kozzi11 at gmail.com> 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 <digitalmars-d-learn at puremagic.com> 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;
>> }
>> ```
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d-learn/attachments/20180407/76bd3fba/attachment.html>


More information about the Digitalmars-d-learn mailing list