Математическая оптимизация в C # - PullRequest
53 голосов
/ 05 января 2009

Я профилировал приложение весь день и, оптимизировав пару бит кода, я остался с этим в моем списке задач. Это функция активации для нейронной сети, которая вызывается более 100 миллионов раз. Согласно dotTrace, это составляет около 60% от общего времени работы.

Как бы вы оптимизировали это?

public static float Sigmoid(double value) {
    return (float) (1.0 / (1.0 + Math.Pow(Math.E, -value)));
}

Ответы [ 24 ]

0 голосов
/ 09 июля 2017

Я видел, что многие люди здесь пытаются использовать приближение, чтобы сделать сигмоид быстрее. Тем не менее, важно знать, что сигмоид также может быть выражен с использованием tanh, а не только exp. Этот способ вычисления сигмоида примерно в 5 раз быстрее, чем с экспоненциальным, и, используя этот метод, вы ничего не приближаете, поэтому исходное поведение сигмоиды сохраняется как есть.

    public static double Sigmoid(double value)
    {
        return 0.5d + 0.5d * Math.Tanh(value/2);
    }

Конечно, parellization будет следующим шагом к повышению производительности, но что касается необработанных вычислений, использование Math.Tanh быстрее, чем Math.Exp.

0 голосов
/ 05 января 2009

Делая поиск в Google, я нашел альтернативную реализацию функции Sigmoid.

public double Sigmoid(double x)
{
   return 2 / (1 + Math.Exp(-2 * x)) - 1;
}

Это правильно для ваших нужд? Это быстрее?

http://dynamicnotions.blogspot.com/2008/09/sigmoid-function-in-c.html

0 голосов
/ 05 января 2009

1) Вы называете это только из одного места? Если это так, вы можете получить небольшую производительность, переместив код из этой функции и просто поместив его туда, где вы обычно вызывали бы функцию Sigmoid. Мне не нравится эта идея с точки зрения читабельности кода и организации, но когда вам нужно получить каждый последний выигрыш в производительности, это может помочь, потому что я думаю, что вызовы функций требуют проталкивания регистров в стеке, чего можно было бы избежать, если код был весь встроенный.

2) Я понятия не имею, может ли это помочь, но попробуйте сделать ваш параметр функции параметром ref. Посмотри, быстрее ли это. Я бы предложил сделать его const (что было бы оптимизацией, если бы это было в c ++), но c # не поддерживает параметры const.

0 голосов
/ 05 января 2009

Если вам нужен гигантский прирост скорости, вы, вероятно, могли бы рассмотреть распараллеливание функции с помощью (ge) силы. IOW, используйте DirectX для управления видеокартой, чтобы сделать это для вас. Я понятия не имею, как это сделать, но я видел, как люди используют видеокарты для всех видов вычислений.

...