Math optimization in C#

后端 未结 25 2188
悲&欢浪女
悲&欢浪女 2020-12-07 10:25

I\'ve been profiling an application all day long and, having optimized a couple bits of code, I\'m left with this on my todo list. It\'s the activation function for a neural

25条回答
  •  囚心锁ツ
    2020-12-07 10:54

    This is slightly off topic, but just out of curiosity, I did the same implementation as the one in C, C# and F# in Java. I'll just leave this here in case someone else is curious.

    Result:

    $ javac LUTTest.java && java LUTTest
    Max deviation is 0.001664
    10^7 iterations using sigmoid1() took 1398 ms
    10^7 iterations using sigmoid2() took 177 ms
    

    I suppose the improvement over C# in my case is due to Java being better optimized than Mono for OS X. On a similar MS .NET-implementation (vs. Java 6 if someone wants to post comparative numbers) I suppose the results would be different.

    Code:

    public class LUTTest {
        private static final float SCALE = 320.0f;
        private static final  int RESOLUTION = 2047;
        private static final  float MIN = -RESOLUTION / SCALE;
        private static final  float MAX = RESOLUTION / SCALE;
    
        private static final float[] lut = initLUT();
    
        private static float[] initLUT() {
            float[] lut = new float[RESOLUTION + 1];
    
            for (int i = 0; i < RESOLUTION + 1; i++) {
                lut[i] = (float)(1.0 / (1.0 + Math.exp(-i / SCALE)));
            }
            return lut;
        }
    
        public static float sigmoid1(double value) {
            return (float) (1.0 / (1.0 + Math.exp(-value)));
        }
    
        public static float sigmoid2(float value) {
            if (value <= MIN) return 0.0f;
            if (value >= MAX) return 1.0f;
            if (value >= 0) return lut[(int)(value * SCALE + 0.5f)];
            return 1.0f - lut[(int)(-value * SCALE + 0.5f)];
        }
    
        public static float error(float v0, float v1) {
            return Math.abs(v1 - v0);
        }
    
        public static float testError() {
            float emax = 0.0f;
            for (float x = -10.0f; x < 10.0f; x+= 0.00001f) {
                float v0 = sigmoid1(x);
                float v1 = sigmoid2(x);
                float e = error(v0, v1);
                if (e > emax) emax = e;
            }
            return emax;
        }
    
        public static long sigmoid1Perf() {
            float y = 0.0f;
            long t0 = System.currentTimeMillis();
            for (int i = 0; i < 10; i++) {
                for (float x = -5.0f; x < 5.0f; x+= 0.00001f) {
                    y = sigmoid1(x);
                }
            }
            long t1 = System.currentTimeMillis();
            System.out.printf("",y);
            return t1 - t0;
        }    
    
        public static long sigmoid2Perf() {
            float y = 0.0f;
            long t0 = System.currentTimeMillis();
            for (int i = 0; i < 10; i++) {
                for (float x = -5.0f; x < 5.0f; x+= 0.00001f) {
                    y = sigmoid2(x);
                }
            }
            long t1 = System.currentTimeMillis();
            System.out.printf("",y);
            return t1 - t0;
        }    
    
        public static void main(String[] args) {
    
            System.out.printf("Max deviation is %f\n", testError());
            System.out.printf("10^7 iterations using sigmoid1() took %d ms\n", sigmoid1Perf());
            System.out.printf("10^7 iterations using sigmoid2() took %d ms\n", sigmoid2Perf());
        }
    }
    

提交回复
热议问题