jenya7 0 3 января, 2017 Опубликовано 3 января, 2017 (изменено) · Жалоба У меня есть 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; } Ворос как предпочтительней? мне кажется второй вариан более риалтаймовый. Изменено 3 января, 2017 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 3 января, 2017 Опубликовано 3 января, 2017 · Жалоба интрига. Где массивы ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexunder 4 3 января, 2017 Опубликовано 3 января, 2017 · Жалоба интрига. Где массивы ? предположу, что имелись ввиду физические массивы датчиков, а не массивы как тип данных. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 3 января, 2017 Опубликовано 3 января, 2017 · Жалоба интрига. Где массивы ? внутри функций typedef struct TASK_S { //fields }TASK; TASK tasks[20]; typedef struct SENSOR_S { //fields }SENSOR; SENSOR sensors[20]; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 3 января, 2017 Опубликовано 3 января, 2017 · Жалоба Если реалтайм, то второй вариант лучше - нет накладных расходов на организацию второго цикла. Если нужен быстрый опрос - лучше использовать не массивы с индексацийе, а указатель с инкриментом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jenya7 0 3 января, 2017 Опубликовано 3 января, 2017 (изменено) · Жалоба Если реалтайм, то второй вариант лучше - нет накладных расходов на организацию второго цикла. Если нужен быстрый опрос - лучше использовать не массивы с индексацийе, а указатель с инкриментом. а с указателем это как? Кстати я тут подумал - задачи пользуются показаниями датчиков. Наверное правильней будет так. while (1) { for (int i = 0; i < 20; i++) { ScanSensor(i); } EvaluateTask(k); k++; if (k > 20) k = 0; } Как вы считаете? Изменено 3 января, 2017 пользователем Jenya7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 3 января, 2017 Опубликовано 3 января, 2017 · Жалоба . . . . Как вы считаете? Что мешает сделать так - по крайней мере читабельно 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 0 3 января, 2017 Опубликовано 3 января, 2017 · Жалоба Что мешает сделать так - по крайней мере читабельно 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 0 3 января, 2017 Опубликовано 3 января, 2017 · Жалоба на операции индексации массива .... Или да, или нет. Зависит от компилятора и системы команд. Поскольку за последние пару десятков лет со времени K155ЛА3 :) компиляторы круто развились в сторону оптимизации, то наиболее вероятный ответ - пофиг. Да и старые времена с дерьмовой оптимизацией все зависело от системы команд - вместо инкрементирования какого нибудь 32bit указателя на 16bit платформе, команда косвенной адресации с дополнительным индексным регистром работала быстрее. Ну а Автору вопроса, вместо заваливания форума вопросами ни о чем, следует научиться САМОСТОЯТЕЛЬНО просматривать листинги. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 26 3 января, 2017 Опубликовано 3 января, 2017 · Жалоба . . . . Поскольку за последние пару десятков лет со времени K155ЛА3 :) . . . . Не пару, а 3-4 :) Желающие помочь оптимизатору компилятра в его нелегких трудах могут это уточнить по листингу асм компилятора :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 3 января, 2017 Опубликовано 3 января, 2017 · Жалоба Не пару, а 3-4 :) Да нет, после 2000 года уже я не встречал эффекта у Си компиляторов от использования нативных для Си указателей вместо индексируемых массивов. Ну а в 90x годах, какой нибудь, например, Борлондячий компилятор, тот да, мог. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 6 января, 2017 Опубликовано 6 января, 2017 · Жалоба Желающие помочь оптимизатору компилятра в его нелегких трудах могут это уточнить по листингу асм компилятора :) Вы удивитесь если просмотрите листинги от некоторых оптимизирующих компиляторов: у некоторых как раз Ваш "оптимизированный вариант", где Вы пытались помочь компилятору, создав указатели и т.п. вместо индексов, даст более объёмный или более медленный код. Я раньше когда-то тоже старался перевести всё на указатели, уменьшить кол-во переменных внутри функции заменив скажем тривиальный: 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. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 6 января, 2017 Опубликовано 6 января, 2017 · Жалоба Команды ARM и Cortex разработаны для индексной арифметики, помимо адресной. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
slavka012 0 10 января, 2017 Опубликовано 10 января, 2017 · Жалоба Вы удивитесь если просмотрите листинги от некоторых оптимизирующих компиляторов: у некоторых как раз Ваш "оптимизированный вариант", где Вы пытались помочь компилятору, создав указатели и т.п. вместо индексов, даст более объёмный или более медленный код. Я раньше когда-то тоже старался перевести всё на указатели, уменьшить кол-во переменных внутри функции заменив скажем тривиальный: 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 это коненчо бесполезно :) Интересно! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться