Оптимизация вычислений

Про байтики и логику ЭБУ
User avatar
Sergey89
contributor
contributor
Posts: 839
Joined: Wed Sep 25, 2013 5:30 pm
Location: Russia, Velikiy Novgorod

Оптимизация вычислений

Post by Sergey89 »

Попробовал сравнить find_index для таблицы линейным перебором и с сохранением предыдущего индекса.

Для теста взял таблицу из 32 значений. Сделал 32 итерации, так чтобы индекс каждый раз увеличивался на 1. В итоге оптимизированный варианта выиграл по скорости примерно 3 раза.

Если индекс не изменяется, то оптимизированный вариант проигрывает пока значение сидит в первых двух ячейках максимум в 1.5 раза, по следующим индексам уже начинает выигрывать.

Code: Select all

unsigned int find_index1(float *x, unsigned int n, float const s[])
{
    if (*x <= s[0])
    {
        *x = s[0];

        return 0;
    }

    n--;

    if (*x >= s[n])
    {
        *x = s[n];

        return n;
    }

    for (unsigned int i = 1; i <= n; i++)
    {
        if (*x < s[i])
        {
            return (i - 1);
        }
    }
}

unsigned int find_index2(float *x, unsigned int p, unsigned int n, float const s[])
{
    if (*x <= s[0])
    {
        *x = s[0];

        return 0;
    }

    n--;

    if (*x >= s[n])
    {
        *x = s[n];

        return n;
    }

    if (*x < s[p])
    {
        p--;

        for (; p >= 0; p--)
        {
            if (*x >= s[p])
            {
                return p;
            }
        }
    }
    else
    {
        p++;

        for (; p <= n; p++)
        {
            if (*x < s[p])
            {
                return (p - 1);
            }
        }
    }
}
User avatar
AndreyB
Site Admin
Posts: 14331
Joined: Wed Aug 28, 2013 1:28 am
Location: Jersey City
Github Username: rusefillc
Slack: Andrey B

Re: Оптимизация вычислений

Post by AndreyB »

Всё это очень мутная тема:

Проблема с оптимизацией - нужно сначала объективными средствами мониторинга и профилирования вообще понять, где именно узкое место. А у нас этого еще совсем нет.

Вторая проблема: микро-текст произодительности идеальный написать тоже непросто. Нам еще относительно проще, у нас не очень навороченный процессор - но с процессорами большими там начинаются шумы предсказаний ветвления и так далее.

И всё этого очень субъективно. Поэтому например касательно findIndex выскажу просто мнение:
Линейный алгоритм, который есть сейчас: по-большому счёту, сомневаюсь что в нём есть проблемы. не так часто вызываем, цена - всего лишние 30 тиков.

Бинарный поиск: риск сделать ошибку сильно выше, но вроде бы достаточно реально покрыть реализацию тестом и можно проверить. Я не буду возражать против бинарного поиска, он _наверное_ что-то ускорит, никак кажется не навредив (кроме повышения риска бага). Такая оптимизация успокоит нас психологически, в итоге она имеет право на существование.

Линейный поиск с запоминанием индекса: вот тут уже я буду против. риска уже больше, уже появляются новые переменные для хранения индекса - значит изменение уже намного больше, а мы до сих пор даже не доказали, что изменение вообще нужно. Такая оптимизация - с моей точки зрения сейчас вредная.
Very limited telepathic abilities - please post logs & tunes where appropriate - http://rusefi.com/s/questions

Always looking for C/C++/Java/PHP developers! Please help us see https://rusefi.com/s/howtocontribute
User avatar
Sergey89
contributor
contributor
Posts: 839
Joined: Wed Sep 25, 2013 5:30 pm
Location: Russia, Velikiy Novgorod

Re: Оптимизация вычислений

Post by Sergey89 »

Предполагается, что функция интерполяции будет вызываться чаще всего. В том числе из задач с высоким приоритетом. Но выбор того или иного метода оптимизации основан в том числе и на характере изменений параметров и на рабочих диапазонах. Пока что, наверное, трудно определить эти характеристики.

Бинарный поиск я тоже попробовал. По сравнению с линейным он начинает выигрывать только ближе к половине шкалы.
User avatar
AndreyB
Site Admin
Posts: 14331
Joined: Wed Aug 28, 2013 1:28 am
Location: Jersey City
Github Username: rusefillc
Slack: Andrey B

Re: Оптимизация вычислений

Post by AndreyB »

Sergey89 wrote:Предполагается, что...
По моему опыту в индустрии: ресурсы обычно тратятся совсем не на то, на что предполагалось они будуд тратиться. Невозможно угадать к сожалению :(
Very limited telepathic abilities - please post logs & tunes where appropriate - http://rusefi.com/s/questions

Always looking for C/C++/Java/PHP developers! Please help us see https://rusefi.com/s/howtocontribute
nikll
Posts: 186
Joined: Tue Oct 15, 2013 5:45 am

Re: Оптимизация вычислений

Post by nikll »

Sergey89 касательно функции интерполяции прав. Пока ее можно не оптимизировать но то что она станет первым местом в поисках оптимизации - это факт. Но сейчас на это можно смело забить, проделанно 1% работы, свободных ресурсов чуть больше чем дохрена, смысл сейчас тратить на это время?
User avatar
Sergey89
contributor
contributor
Posts: 839
Joined: Wed Sep 25, 2013 5:30 pm
Location: Russia, Velikiy Novgorod

Re: Оптимизация вычислений

Post by Sergey89 »

Ну я считаю так, что если есть желание что-то сделать, то лучше сделать а не откладывать на потом :)
nikll
Posts: 186
Joined: Tue Oct 15, 2013 5:45 am

Re: Оптимизация вычислений

Post by nikll »

Sergey89 wrote:Ну я считаю так, что если есть желание что-то сделать, то лучше сделать а не откладывать на потом :)
Ну дак тебе же никто не запрещает ) делай. Я тоже бывает ради фана что-нибудь ковыряю. Счас вот логгером занялся, изобретаю как через кучку ОУ, незаметно для ЭБУ, снимать с моторной проводки сигналы, цель - отработать полуавтоматическую генерацию карт под конкретный движок для легкой замены родного ЭБУ на свой. Это ладно тупой тазовский движок откалибровать, а вот виэйт с vvti и акпп откатать довольно сложно будет. В общем не буду разводить флуд, как закончу хотябы частично создам тему про логгер.
А про оптимизации можно сказать только одно, на данном этапе, с точни зрения стратегии разработки, смысла тратить на это время нет, лудьше сделать чтонибудь полезное )
User avatar
AndreyB
Site Admin
Posts: 14331
Joined: Wed Aug 28, 2013 1:28 am
Location: Jersey City
Github Username: rusefillc
Slack: Andrey B

Re: Оптимизация вычислений

Post by AndreyB »

nikll wrote:смысл сейчас тратить на это время?
Сделать бинарные поиск вряд ли вредно, а психологический эффект тоже важный эффект. Буду рад патчу бинарного поиска, обещаю написать тест и быстро закоммитить.
Very limited telepathic abilities - please post logs & tunes where appropriate - http://rusefi.com/s/questions

Always looking for C/C++/Java/PHP developers! Please help us see https://rusefi.com/s/howtocontribute
User avatar
Sergey89
contributor
contributor
Posts: 839
Joined: Wed Sep 25, 2013 5:30 pm
Location: Russia, Velikiy Novgorod

Re: Оптимизация вычислений

Post by Sergey89 »

Code: Select all

int findIndex(float const array[], int size, float value)
{
    int m, l, h;

    if (value <= array[0])
    {
        return 0;
    }

    if (value >= array[(size - 1)])
    {
        return (size - 1);
    }

    l = 0;
    h = size;

    for (; size > 0; size--) // while (1)
    {
        m = (l + h) >> 1;

        if (m == l)
        {
            break;
        }

        if (value < array[m])
        {
            h = m;
        }
        else if (value > array[m])
        {
            l = m;
        }
        else
        {
            break;
        }
    }

    return m;
}
User avatar
AndreyB
Site Admin
Posts: 14331
Joined: Wed Aug 28, 2013 1:28 am
Location: Jersey City
Github Username: rusefillc
Slack: Andrey B

Re: Оптимизация вычислений

Post by AndreyB »

Сергей, во-первых, у тебя одна или две ошибки - неправильная проверка пограничного условия и возвращается неправильный результат в случае пограничного условия - это про "if (value < array[0]) return -1; ". Это не проблема - я заранее написал тест :) (мой наивный подход к тестированию в https://sourceforge.net/p/rusefi/code/HEAD/tree/trunk/win32_algo_tests/ ). Вторая проверка на второе пограничное условие не нужна, она только замедляет код - проверка выполнится всегда, и 95% случаев она будет зря.

Ну а во-вторых, этот код как будто специально максимально нечитабельный :(

Имена переменный по одной букве? Ну ты что :(

Сдвиг направо вместо деления? Это работа компилятора. Мы тут на C программируем, а не на ассемблере - любой компилятор C выполнит эту оптимизацию за тебя, а ты мучаешь читателей. Пруфлинк - http://stackoverflow.com/questions/2580680/does-a-c-c-compiler-optimize-constant-divisions-by-power-of-two-value-into-shi

for(size--) это с одной стороны хорошо - потому что это такая защита на всякий случай, с другой стороны - ошибка проглатывается втихоря, вместо зависания будет некорректная работа. Я сделал вызов функции "fatal", потому что идея проверка мне в целом нравится.

Итого у меня получилось https://sourceforge.net/p/rusefi/code/HEAD/tree/trunk/firmware/controllers/math/engine_math.c
Еще один тикет закрыт, но там в трекере есть еще :)
Very limited telepathic abilities - please post logs & tunes where appropriate - http://rusefi.com/s/questions

Always looking for C/C++/Java/PHP developers! Please help us see https://rusefi.com/s/howtocontribute
User avatar
Sergey89
contributor
contributor
Posts: 839
Joined: Wed Sep 25, 2013 5:30 pm
Location: Russia, Velikiy Novgorod

Re: Оптимизация вычислений

Post by Sergey89 »

Я наивно предполагал, что перед интерполяцией будет проверка на диапазон :) Правда в этом случае проверка на диапазон в методе поиска индекса вообще лишняя.

То есть что-то типа такого:

Code: Select all

float tableLookup(float const values[], float const scale[], int size, float value)
{
    int index;

    if (value <= scale[0])
    {
        return values[0];
    }
    else if (value >= scale[(size - 1)])
    {
        return values[(size - 1)];
    }
    
    index = findIndex(scale, size, value);

    return interpolate(...);
}
User avatar
AndreyB
Site Admin
Posts: 14331
Joined: Wed Aug 28, 2013 1:28 am
Location: Jersey City
Github Username: rusefillc
Slack: Andrey B

Re: Оптимизация вычислений

Post by AndreyB »

Sergey89 wrote:Я наивно предполагал, что перед интерполяцией будет проверка на диапазон :)
Ну а чего предполагать, если все исходники есть и их можно посмотреть?
Very limited telepathic abilities - please post logs & tunes where appropriate - http://rusefi.com/s/questions

Always looking for C/C++/Java/PHP developers! Please help us see https://rusefi.com/s/howtocontribute
User avatar
Sergey89
contributor
contributor
Posts: 839
Joined: Wed Sep 25, 2013 5:30 pm
Location: Russia, Velikiy Novgorod

Re: Оптимизация вычислений

Post by Sergey89 »

Да. Моя ошибка. Посмотрел предыдущую ревизию, там даже в комментариях написано было :)
User avatar
Sergey89
contributor
contributor
Posts: 839
Joined: Wed Sep 25, 2013 5:30 pm
Location: Russia, Velikiy Novgorod

Re: Оптимизация вычислений

Post by Sergey89 »

Можно оси некоторых таблиц сделать фиксированными. Например температуру можно задать осью от -40 до 110 градусов с шагом 10 градусов. Фиксированный шаг заменит поиск на деление.
User avatar
AndreyB
Site Admin
Posts: 14331
Joined: Wed Aug 28, 2013 1:28 am
Location: Jersey City
Github Username: rusefillc
Slack: Andrey B

Re: Оптимизация вычислений

Post by AndreyB »

Sergey89 wrote:Можно оси некоторых таблиц сделать фиксированными. Например температуру можно задать осью от -40 до 110 градусов с шагом 10 градусов. Фиксированный шаг заменит поиск на деление.
"You are wasting mental energy on silly micro-optimizations. Ignore them until you are forced to confront them (i.e. because your program is running too slowly and a profiler is pointing at them)"
Very limited telepathic abilities - please post logs & tunes where appropriate - http://rusefi.com/s/questions

Always looking for C/C++/Java/PHP developers! Please help us see https://rusefi.com/s/howtocontribute
User avatar
Sergey89
contributor
contributor
Posts: 839
Joined: Wed Sep 25, 2013 5:30 pm
Location: Russia, Velikiy Novgorod

Re: Оптимизация вычислений

Post by Sergey89 »

Это не только вопрос оптимизации скорости, но и вопрос удобства. Нужно ли для каждой таблицы делать свою ось или можно использовать общие. И уже отсюда следует оптимизация.

Эта тема и создана для обсуждения таких вопросов, а не как призыв к действию :)
nikll
Posts: 186
Joined: Tue Oct 15, 2013 5:45 am

Re: Оптимизация вычислений

Post by nikll »

Удобние использовать свое квантирование вместо линейного. Как например вот на этой вот квантируются обороты:
Image

Это позволит повышать точность настроек в нужных местах.
User avatar
Sergey89
contributor
contributor
Posts: 839
Joined: Wed Sep 25, 2013 5:30 pm
Location: Russia, Velikiy Novgorod

Re: Оптимизация вычислений

Post by Sergey89 »

Я сейчас не говорю про все таблицы. Но многие таблицы идут с фиксированным шагом.
frig
contributor
contributor
Posts: 569
Joined: Wed Oct 23, 2013 8:05 pm

Re: Оптимизация вычислений

Post by frig »

Согласен с russian - нет смысла сейчас с этим заморачиваться. Тем более, что вопросы эти не влияют на дальнейшую работу, это обособленный кусок который всегда можно переписать, если это будет нужно. При этом все остальное остается на месте. Интерфейсы сформированы, все работает, дальше покажет время.
skype: frig_frig
User avatar
Maxi
Sr Consultant
Sr Consultant
Posts: 786
Joined: Wed Oct 23, 2013 4:25 pm

Re: Оптимизация вычислений

Post by Maxi »

nikll wrote:Удобние использовать свое квантирование вместо линейного.
Чужое ты хотел сказать квантование....
Для своего нужно сначала с мотором поработать потом с многочленами Чебышева...
User avatar
AndreyB
Site Admin
Posts: 14331
Joined: Wed Aug 28, 2013 1:28 am
Location: Jersey City
Github Username: rusefillc
Slack: Andrey B

Re: Оптимизация вычислений

Post by AndreyB »

А я тут с дрожжанием борюсь, см. http://rusefi.com/forum/viewtopic.php?f=5&t=681

Профайлер нормальный пока не нашёл - так что пока крестьянская методика семплирования http://stackoverflow.com/questions/375913/what-can-i-use-to-profile-c-code-in-linux/378024#378024

Из любопытного - почитываю, что же там компилятор гененирирует, в том числе на уровне O3.

Code: Select all

float a = ...
float rpm = ...
float result = a / (600 / rpm);
печаль - у компилятора не хватает смелости сделать из этого хотя бы

Code: Select all

float result = a * rpm / 600;
Деление на ноль конечно же повод так не делать, так что придётся это делать руками - лишние деления меня раздражают.
Very limited telepathic abilities - please post logs & tunes where appropriate - http://rusefi.com/s/questions

Always looking for C/C++/Java/PHP developers! Please help us see https://rusefi.com/s/howtocontribute
User avatar
AndreyB
Site Admin
Posts: 14331
Joined: Wed Aug 28, 2013 1:28 am
Location: Jersey City
Github Username: rusefillc
Slack: Andrey B

Re: Оптимизация вычислений

Post by AndreyB »

Опять два дня провёл в отладчике - несколько раз неприятно удивился: как-то всё это достаточно межденно работает. Любое тревиальное выражение начинает стоить порядка 10ти тактов видимо за счёт прочитать из памяти-записать в память. Вызов метода - выходит, что стоит порядка 40ка тиков! В итоге начал заменять вызовы тревиальных методов на макросы, красотой приходится жертвовать :(

На 5000 оборотов и 60-2 триггере у нас между взлётом и падением уровня на зубе проходит 100 микросекунд - это всего 16800 тактов процессора. Текущая имплементация логики на первом зубе внутри обработчкика прерывания проводит много рассчётов расписания работы на весь зуб вперёд - при этом эта логика сейчас сама жрёт порядка 10000 тиков, запаса нет никакого.

Пока попробую по крохам заоптимизировать - видимо нужно будет делать пред-рассчёт для линейной интерполяции. Если это не поможет - следующий шаг будет уже переносить рассчёт внутрь пропущенного зуба, там в три раза больше времени доступно. Короче 168 мегагерц быстро подошли к концу :) В ключевые моменты всё в лоб рассчитывать на месте не получается.
Very limited telepathic abilities - please post logs & tunes where appropriate - http://rusefi.com/s/questions

Always looking for C/C++/Java/PHP developers! Please help us see https://rusefi.com/s/howtocontribute
puff
contributor
contributor
Posts: 2961
Joined: Mon Nov 11, 2013 11:28 am
Location: Moskau

Re: Оптимизация вычислений

Post by puff »

как вариант - искусственно загрублять его вдвое не получится?
User avatar
AndreyB
Site Admin
Posts: 14331
Joined: Wed Aug 28, 2013 1:28 am
Location: Jersey City
Github Username: rusefillc
Slack: Andrey B

Re: Оптимизация вычислений

Post by AndreyB »

puff wrote:как вариант - искусственно загрублять его вдвое не получится?
В случае индукционного датчика там даже нужно пропускать половину сигналов, но сначала хочется просто алгоритм попытаться улучшить.
Very limited telepathic abilities - please post logs & tunes where appropriate - http://rusefi.com/s/questions

Always looking for C/C++/Java/PHP developers! Please help us see https://rusefi.com/s/howtocontribute
User avatar
Maxi
Sr Consultant
Sr Consultant
Posts: 786
Joined: Wed Oct 23, 2013 4:25 pm

Re: Оптимизация вычислений

Post by Maxi »

russian wrote: На 5000 оборотов и 60-2 триггере у нас между взлётом и падением уровня на зубе проходит 100 микросекунд - это всего 16800 тактов процессора. Текущая имплементация логики на первом зубе внутри обработчкика прерывания проводит много рассчётов расписания работы на весь зуб вперёд - при этом эта логика сейчас сама жрёт порядка 10000 тиков, запаса нет никакого.
За это время январь выполнит всего то 250 простых команд и ему хватает их так что он крутится 12000.
Короче 168 мегагерц быстро подошли к концу :)
с167 на 40 мегагерцах решает. даже таская за собой RTOS а если ее не таскать - вообще пушка че делает...
User avatar
AndreyB
Site Admin
Posts: 14331
Joined: Wed Aug 28, 2013 1:28 am
Location: Jersey City
Github Username: rusefillc
Slack: Andrey B

Re: Оптимизация вычислений

Post by AndreyB »

Maxi wrote: За это время январь выполнит всего то 250 простых команд и ему хватает их так что он крутится 12000.
Ну вот и мне нужно стремиться к 250ти командам, так что или что-то нужно будет вычислять заранее, или что-то перестать вычислять вообще :)
Very limited telepathic abilities - please post logs & tunes where appropriate - http://rusefi.com/s/questions

Always looking for C/C++/Java/PHP developers! Please help us see https://rusefi.com/s/howtocontribute
User avatar
Maxi
Sr Consultant
Sr Consultant
Posts: 786
Joined: Wed Oct 23, 2013 4:25 pm

Re: Оптимизация вычислений

Post by Maxi »

russian wrote:
Maxi wrote: За это время январь выполнит всего то 250 простых команд и ему хватает их так что он крутится 12000.
Ну вот и мне нужно стремиться к 250ти командам, так что или что-то нужно будет вычислять заранее, или что-то перестать вычислять вообще :)
А что собственно вообще вычислять в задаче обработчика зубьев?!
ни один мозг ТАМ ничего не вычисляет.
все уже вычислено до этого.
User avatar
AndreyB
Site Admin
Posts: 14331
Joined: Wed Aug 28, 2013 1:28 am
Location: Jersey City
Github Username: rusefillc
Slack: Andrey B

Re: Оптимизация вычислений

Post by AndreyB »

Maxi wrote:ни один мозг ТАМ ничего не вычисляет.
все уже вычислено до этого.
на первом зубе каждого цикла:
1) рассчёт времени накопления на текущих оборотах - линейная интерполяция
2) 3D интерполяция угла опережения зажигания - это три линейные интерполяции
3) на основании углов зажигания на всех цилиндах - бинарный поиск индекса зуба триггера, на котором собсвенно должно произойти зажигание в конкретном цилинде
Very limited telepathic abilities - please post logs & tunes where appropriate - http://rusefi.com/s/questions

Always looking for C/C++/Java/PHP developers! Please help us see https://rusefi.com/s/howtocontribute
User avatar
rus084
contributor
contributor
Posts: 678
Joined: Sun Dec 01, 2013 1:40 pm
Location: Russia , Stavropol

Re: Оптимизация вычислений

Post by rus084 »

а нельзя расчет производить частями?
User avatar
AndreyB
Site Admin
Posts: 14331
Joined: Wed Aug 28, 2013 1:28 am
Location: Jersey City
Github Username: rusefillc
Slack: Andrey B

Re: Оптимизация вычислений

Post by AndreyB »

rus084 wrote:а нельзя расчет производить частями?
Можно. Судя по всему, для начала я рассчёт накопления и угла зажигания вынесу с первого зуба на N-ый зуб в соответствии с конфигурацией.
Very limited telepathic abilities - please post logs & tunes where appropriate - http://rusefi.com/s/questions

Always looking for C/C++/Java/PHP developers! Please help us see https://rusefi.com/s/howtocontribute
Post Reply