Цитата(k155la3 @ Jan 3 2017, 16:23)
Желающие помочь оптимизатору компилятра в его нелегких трудах могут это уточнить по листингу асм компилятора
Вы удивитесь если просмотрите листинги от некоторых оптимизирующих компиляторов: у некоторых как раз Ваш "оптимизированный вариант", где Вы пытались помочь компилятору, создав указатели и т.п. вместо индексов, даст более объёмный или более медленный код.
Я раньше когда-то тоже старался перевести всё на указатели, уменьшить кол-во переменных внутри функции заменив скажем тривиальный:
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.