Перейти к содержанию
    

Методология опроса массивов.

У меня есть 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;
}

Ворос как предпочтительней?

мне кажется второй вариан более риалтаймовый.

Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

интрига. Где массивы ?

предположу, что имелись ввиду физические массивы датчиков, а не массивы как тип данных.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

интрига. Где массивы ?

внутри функций

typedef struct TASK_S
{
     //fields    
}TASK;

TASK tasks[20];

typedef struct SENSOR_S
{
     //fields
}SENSOR;

SENSOR sensors[20];

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если реалтайм, то второй вариант лучше - нет накладных расходов на организацию второго цикла.

Если нужен быстрый опрос - лучше использовать не массивы с индексацийе, а указатель с инкриментом.

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если реалтайм, то второй вариант лучше - нет накладных расходов на организацию второго цикла.

Если нужен быстрый опрос - лучше использовать не массивы с индексацийе, а указатель с инкриментом.

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

 

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

while (1)
{    

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

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

}

Как вы считаете?

Изменено пользователем Jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

. . . .

Как вы считаете?

 

Что мешает сделать так - по крайней мере читабельно

    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;

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что мешает сделать так - по крайней мере читабельно

    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;

 

я понял. спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

на операции индексации массива

....

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

 

Ну а Автору вопроса, вместо заваливания форума вопросами ни о чем, следует научиться САМОСТОЯТЕЛЬНО просматривать листинги.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

. . . . Поскольку за последние пару десятков лет со времени K155ЛА3 :)

. . . .

Не пару, а 3-4 :)

Желающие помочь оптимизатору компилятра в его нелегких трудах могут это уточнить по листингу асм компилятора :)

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не пару, а 3-4 :)

Да нет, после 2000 года уже я не встречал эффекта у Си компиляторов от использования нативных для Си указателей вместо индексируемых массивов.

Ну а в 90x годах, какой нибудь, например, Борлондячий компилятор, тот да, мог.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Желающие помочь оптимизатору компилятра в его нелегких трудах могут это уточнить по листингу асм компилятора :)

Вы удивитесь если просмотрите листинги от некоторых оптимизирующих компиляторов: у некоторых как раз Ваш "оптимизированный вариант", где Вы пытались помочь компилятору, создав указатели и т.п. вместо индексов, даст более объёмный или более медленный код.

Я раньше когда-то тоже старался перевести всё на указатели, уменьшить кол-во переменных внутри функции заменив скажем тривиальный:

for (i=0; i < N; i++) a += m1 + 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 гораздо проще, но всё же тоже часто оптимизатор очень сильно преобразует простой шаблонный код, в корне меняя его скорость.

 

я понял. спасибо.

Спасибо говорить рано. Оптимизирующий компилятор для первого и для второго варианта может выдать примерно одинаковый код, что-нить типа

a=m[i];
i++; 
b=m[i];

преобразовав в одну инструкцию LDRD.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Команды ARM и Cortex разработаны для индексной арифметики, помимо адресной.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы удивитесь если просмотрите листинги от некоторых оптимизирующих компиляторов: у некоторых как раз Ваш "оптимизированный вариант", где Вы пытались помочь компилятору, создав указатели и т.п. вместо индексов, даст более объёмный или более медленный код.

Я раньше когда-то тоже старался перевести всё на указатели, уменьшить кол-во переменных внутри функции заменив скажем тривиальный:

for (i=0; i < N; i++) a += m1 + 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 это коненчо бесполезно :) Интересно!

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...