Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Методология опроса массивов.
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Jenya7
У меня есть 20 задач и 20 датчиков. Их надо опросить.
Можно сделать так.
Код
while (1)
{
    for (int I = 0; I < 20; i++)
    {
        EvaluateTask(i);
    }

    for (int I = 0; I < 20; i++)
    {
        ScanSensor(i);
    }
}

или так
Код
while (1)
{
    EvaluateTask(i);

    ScanSensor(i);

    i++;
    if (i >= 20)
        i = 0;
}

Ворос как предпочтительней?
мне кажется второй вариан более риалтаймовый.
k155la3
интрига. Где массивы ?
alexunder
Цитата(k155la3 @ Jan 3 2017, 10:42) *
интрига. Где массивы ?

предположу, что имелись ввиду физические массивы датчиков, а не массивы как тип данных.
Jenya7
Цитата(k155la3 @ Jan 3 2017, 15:42) *
интрига. Где массивы ?

внутри функций
Код
typedef struct TASK_S
{
     //fields    
}TASK;

TASK tasks[20];

typedef struct SENSOR_S
{
     //fields
}SENSOR;

SENSOR sensors[20];
k155la3
Если реалтайм, то второй вариант лучше - нет накладных расходов на организацию второго цикла.
Если нужен быстрый опрос - лучше использовать не массивы с индексацийе, а указатель с инкриментом.



Jenya7
Цитата(k155la3 @ Jan 3 2017, 16:11) *
Если реалтайм, то второй вариант лучше - нет накладных расходов на организацию второго цикла.
Если нужен быстрый опрос - лучше использовать не массивы с индексацийе, а указатель с инкриментом.

а с указателем это как?

Кстати я тут подумал - задачи пользуются показаниями датчиков. Наверное правильней будет так.
Код
while (1)
{    

    for (int i = 0; i < 20; i++)
    {
        ScanSensor(i);
    }

    EvaluateTask(k);
     k++;
     if (k > 20)
         k = 0;

}

Как вы считаете?
k155la3
Цитата(Jenya7 @ Jan 3 2017, 13:16) *
. . . .
Как вы считаете?


Что мешает сделать так - по крайней мере читабельно
Код
    for (int i = 0; i < 20; i++)
    {
        ScanSensor(i); - опросить датчик
        EvaluateTask(i); - выполнить расчет (или что там)
    }


По указателям.
на операции индексации массива
Код
a=m[i];
i++;
a=m[i];
уходит больше времени чем на
Код
a=*p_m;
p_m++;
a=*p_m;


Jenya7
Цитата(k155la3 @ Jan 3 2017, 17:50) *
Что мешает сделать так - по крайней мере читабельно
Код
    for (int i = 0; i < 20; i++)
    {
        ScanSensor(i); - опросить датчик
        EvaluateTask(i); - выполнить расчет (или что там)
    }


По указателям.
на операции индексации массива
Код
a=m[i];
i++;
a=m[i];
уходит больше времени чем на
Код
a=*p_m;
p_m++;
a=*p_m;


я понял. спасибо.
zltigo
Цитата(k155la3 @ Jan 3 2017, 13:50) *
на операции индексации массива
....

Или да, или нет. Зависит от компилятора и системы команд. Поскольку за последние пару десятков лет со времени K155ЛА3 sm.gif компиляторы круто развились в сторону оптимизации, то наиболее вероятный ответ - пофиг. Да и старые времена с дерьмовой оптимизацией все зависело от системы команд - вместо инкрементирования какого нибудь 32bit указателя на 16bit платформе, команда косвенной адресации с дополнительным индексным регистром работала быстрее.

Ну а Автору вопроса, вместо заваливания форума вопросами ни о чем, следует научиться САМОСТОЯТЕЛЬНО просматривать листинги.
k155la3
Цитата(zltigo @ Jan 3 2017, 16:11) *
. . . . Поскольку за последние пару десятков лет со времени K155ЛА3 sm.gif
. . . .

Не пару, а 3-4 sm.gif
Желающие помочь оптимизатору компилятра в его нелегких трудах могут это уточнить по листингу асм компилятора sm.gif

zltigo
Цитата(k155la3 @ Jan 3 2017, 15:23) *
Не пару, а 3-4 sm.gif

Да нет, после 2000 года уже я не встречал эффекта у Си компиляторов от использования нативных для Си указателей вместо индексируемых массивов.
Ну а в 90x годах, какой нибудь, например, Борлондячий компилятор, тот да, мог.
jcxz
Цитата(k155la3 @ Jan 3 2017, 16:23) *
Желающие помочь оптимизатору компилятра в его нелегких трудах могут это уточнить по листингу асм компилятора sm.gif

Вы удивитесь если просмотрите листинги от некоторых оптимизирующих компиляторов: у некоторых как раз Ваш "оптимизированный вариант", где Вы пытались помочь компилятору, создав указатели и т.п. вместо индексов, даст более объёмный или более медленный код.
Я раньше когда-то тоже старался перевести всё на указатели, уменьшить кол-во переменных внутри функции заменив скажем тривиальный:
for (i=0; i < N; i++) a += m1[i] + m2[i*2+OFFSET];
на что-нить типа:
int *p1 = &m1[0], *p2 = &m2[OFFSET], *pe = &m1[N];
do {
a += *p1++ + *p2;
p2 += 2;
} while (p1 != pe);
казалось-бы - по количеству операций здесь меньше, си-код получается ближе к целевому асм-коду и асм-код должен быть короче и быстрее (я вроде как полработы сделал за компилятор).
Но когда посмотрел на листинги компиляции (и замерил скорость выполнения) для первого и 2-го случаев для Code Composer Studio для DSP на VLIW-ядре с максимальной оптимизацией, то очень удивился.
Для первого случая компилятор делал очень сильное преобразование алгоритма, иногда он становился практически неузнаваемым (частично раскручивал циклы, спаривал ветви выполнения, размножал переменные в несколько регистров, переставлял и конвееризировал операции, применял сложные инструкции CPU выполняющие много действий и т.п.).
А вот для второго случая компилятор обычно гораздо меньше менял алгоритм таких циклов.
В результате для подобных двух вариантов 1-й вариант выигрывал у второго по скорости иногда даже В РАЗЫ!!!
Я понял, что в ряде случаев для оптимизирующего компилятора, чем проще и шаблоннее выглядит код, тем легче ему оптимизировать и результат получается лучше.
Да, размер такого кода получается часто больше, чем размер "вручную оптимизированного", но зато скорость...
А как только начинаешь думать как оптимальнее сделать операции и выполнить часть работы за компилятор - код получается медленнее. Так что после этого, я даже во всех местах, где критична была большая скорость выполнения, переписал такие функции в самые простые варианты.
Для компиляторов на Cortex-M это менее критично, так как простор для оптимизации здесь меньше, исполняющее ядро CPU гораздо проще, но всё же тоже часто оптимизатор очень сильно преобразует простой шаблонный код, в корне меняя его скорость.

Цитата(Jenya7 @ Jan 3 2017, 15:09) *
я понял. спасибо.

Спасибо говорить рано. Оптимизирующий компилятор для первого и для второго варианта может выдать примерно одинаковый код, что-нить типа
Код
a=m[i];
i++;
b=m[i];
преобразовав в одну инструкцию LDRD.
ViKo
Команды ARM и Cortex разработаны для индексной арифметики, помимо адресной.
ar__systems
Цитата(jcxz @ Jan 6 2017, 03:42) *
Вы удивитесь если просмотрите листинги от некоторых оптимизирующих компиляторов: у некоторых как раз Ваш "оптимизированный вариант", где Вы пытались помочь компилятору, создав указатели и т.п. вместо индексов, даст более объёмный или более медленный код.
Я раньше когда-то тоже старался перевести всё на указатели, уменьшить кол-во переменных внутри функции заменив скажем тривиальный:
for (i=0; i < N; i++) a += m1[i] + m2[i*2+OFFSET];
на что-нить типа:
int *p1 = &m1[0], *p2 = &m2[OFFSET], *pe = &m1[N];
do {
a += *p1++ + *p2;
p2 += 2;
} while (p1 != pe);
казалось-бы - по количеству операций здесь меньше, си-код получается ближе к целевому асм-коду и асм-код должен быть короче и быстрее (я вроде как полработы сделал за компилятор).
Но когда посмотрел на листинги компиляции (и замерил скорость выполнения) для первого и 2-го случаев для Code Composer Studio для DSP на VLIW-ядре с максимальной оптимизацией, то очень удивился.

Оптимизация законная, если говорить про RISC и другие простые архитектуры. Оптимизировать вручную для VLIW это коненчо бесполезно sm.gif Интересно!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.