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

Кто тестировал IAR ARM 8.50, отзовитесь

8 минут назад, __inline__ сказал:

Ну и то же руководство по сборке gentoo linux, не рекомендует собирать его с опциями выше, чем -O2.  Потому что разработчики ядра не гарантируют работоспособность ядра на -O3 и -Ofast.

Выходит, по-вашему,  ядро тоже бажное?

Конечно. Извините, но "разработчики некоего ядра" для меня не являются неоспоримыми авторитетами в последней инстанции. :unknw:

Неоспоримым доказательством наличия бага компилятора является только приведение конкретного примера кода и листинга его компиляции

Цитата

Но есть тенденция, что у GCC больше шансов сделать код рабочим на -O3 или fast, чем у IAR.

Код, который компилится в работоспособный только с некоторыми шансами, уже по определению - кривой.

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


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

5 minutes ago, __inline__ said:

 

Прямо всех?  С -Wall и pedantic + Werror ?

Да. Wall, Wextra, pedantic. Werror мне не нужен, поскольку 0 предупреждений, это 0 предупреждений.

7 minutes ago, jcxz said:

А на каком ядре HF "не может быть по определению"?

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

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

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


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

6 минут назад, one_eight_seven сказал:

В Linux есть и другое объяснение, я не собирал Gentoo, я больше по RedHat'ам, но там объяснение такое, что -O2 выбрано из-за того, что -O3, -Ofast используют агрессивный инлайнинг и это увеличивает cache footprint приложений, что резко негативно сказывается на производительности.

С этим согласен. Сам такое наблюдал не раз в листингах: на максимальной оптимизации по скорости, компиляторы иногда делают такое, что код становится более тормозным, чем на средней оптимизации. Но при этом он остаётся рабочим.

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

 

PS: Да и оптимизация по скорости может приводить к сильному раздуванию использования стека.

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


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

13 минут назад, jcxz сказал:

А на каком ядре HF "не может быть по определению"?

Да может, конечно, если уж к буквам придираться. Но ожидать, что компилятор от разработчиков ядра устроит HardFault у Cortex-M4 вот на таком коде при операции чтения из памяти...

void WriteFIFO(uint8_t *src)
{
  uit32_t *fifo = CONST;
  *fifo = *(uint32_t *)src;
}

 

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


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

29 минут назад, VladislavS сказал:

Да может, конечно, если уж к буквам придираться. Но ожидать, что компилятор от разработчиков ядра устроит HardFault у Cortex-M4 вот на таком коде при операции чтения из памяти...


void WriteFIFO(uint8_t *src)
{
  uit32_t *fifo = CONST;
  *fifo = *(uint32_t *)src;
}

 

Ну так код то кривой. Разве не видите сами? :unknw:

Компилятор вправе устроить HF на таком. Бага компилятора нет.

 

PS: Я в таких случаях пишу так:

*fifo = *(u32p8 *)src;

набор пакованных типов uXXpYY у меня описан:

typedef __packed u16 u16p8;
typedef __packed s16 s16p8;
typedef __packed u32 u32p8;
typedef __packed s32 s32p8;
typedef __packed u64 u64p8;
typedef __packed s64 s64p8;

И тогда компилятор использует только инструкции LDR.

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


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

Чего это он кривой? СПЕЦИАЛЬНО произведено чтение 32-битного слова по невыровненному адресу. Cortex-M4  это позволяет делать. Почему компилятор от разработчиков ядра выбрал неподходящую для этого инструкцию?

*src + (*(src+1)<<8) + (*(src+2)<<16) + (*(src+3)<<24);

Вот такую операцию он тоже оптимизирует до одного 32-битного чтения, но использует уже правильную инструкцию. То есть, компилятор знает, что на этом ядре так можно. Но пользуется этим знанием как-то странно.

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


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

9 minutes ago, jcxz said:

Ну так код то кривой. Разве не видите сами? :unknw:

Компилятор вправе устроить HF на таком. Бага компилятора нет.

 

PS: Я в таких случаях пишу так:

*fifo = *(u32p8 *)src;

набор пакованных типов uXXpYY у меня описан:

 

Это уже слишком нагло со стороны компилятора.  Есть соглашение, что переменные должны быть выравнены на 4 байта в режиме ARM.

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


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

Только что, __inline__ сказал:

Это уже слишком нагло со стороны компилятора.  Есть соглашение, что переменные должны быть выравнены на 4 байта в режиме ARM.

8-разрядные???  :shok:  Это где такое написано?

И при чём тут переменные и их выравнивание? Вы посмотрите откуда берётся s - где там какая-то переменная?

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


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

Just now, __inline__ said:

Это уже слишком нагло со стороны компилятора.  Есть соглашение, что переменные должны быть выравнены на 4 байта в режиме ARM.

Там у вас проблема не в переменной, а в адресе, т.е. значении, которое хранится в переменной. Адрес, по которому вы пытаетесь считать 32-разрядную переменную может быть выровнен по 8 байт.

Пример - вы хотите взять второй байт в 32-разрядном слове (интерпретировать его как массив байт [0:3], и обратиться ко второму элементу. Адрес второго элемента не будет выровнен по границе 32 бита. Это аргумент (функции uint8_t * src). И это не должно быть запрещено компилятором. Оно не запрещено.

А далее вы по этому адресу берёте не 1 байт, а 4, которые уже должны бы быть выровнены по границе 32 бита, а оно не так (см. предыдущий параграф)

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


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

4 минуты назад, VladislavS сказал:

Чего это он кривой? СПЕЦИАЛЬНО произведено чтение 32-битного слова по невыровненному адресу. Cortex-M4  это позволяет делать. Почему компилятор от разработчиков ядра выбрал неподходящую для этого инструкцию?

Потому что Вы явно указали компилятору, что адресуете 32-битное значение, которые он по умолчанию считает выровненными (в целях оптимизации). Иначе - надо явно указывать, что значение не выровнено (как у меня или в опциях компилятора).

А компилятор вправе выбирать любую инструкцию из доступных в ядре для доступа к значениям известного ему типа. В том числе и STRD/STM/STREX/... - как будет удобнее в целях оптимизации кода.

4 минуты назад, VladislavS сказал:

*src + (*(src+1)<<8) + (*(src+2)<<16) + (*(src+3)<<24);

Вот такую операцию он тоже оптимизирует до одного 32-битного чтения, но использует уже правильную инструкцию.

Это просто случай. Просто  в данном конкретном месте оказалось удобнее использовать именно LDR, а не LDM например.

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


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

Адрес src на вход функции подаётся в общем случае невыровненный. По этому адресу читается 4 байта. Если бы это был Cortex-M0 какой-нибудь, то компилятор в несколько присестов как-нибудь собрал прочитал эти байты из памяти. Но тут он видит, что у него Cortex-M4 и можно с понтами сразу 32-битное чтение применить и выбирает неправильную инструкцию.

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


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

Только что, VladislavS сказал:

Но тут он видит, что у него Cortex-M4 и можно с понтами сразу 32-битное чтение применить и выбирает неправильную инструкцию.

Вы бы хоть привели этот "неправильный" листинг во что это скомпилировалось....

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


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

2 минуты назад, jcxz сказал:

что адресуете 32-битное значение, которые он по умолчанию считает выровненными (в целях оптимизации)

С чего бы это? Кто так умолчал? 32-битное значение легко может быть частью упакованной структуры.

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


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

9 minutes ago, jcxz said:

8-разрядные???  :shok:  Это где такое написано?

И при чём тут переменные и их выравнивание? Вы посмотрите откуда берётся s - где там какая-то переменная?

 

22 minutes ago, jcxz said:

void WriteFIFO(uint8_t *src) { uit32_t *fifo = CONST; *fifo = *(uint32_t *)src; }

 

Да какая фиг разница?  Если это указатель, то он уже обязан быть выровнен на 4 байта как минимум, если он аргумент функции.  Для остальных случаев есть packed и всё с ним связанное.  То что вы привели, это - костыли для компилятора чтобы избежать случая, описанного VladislavS

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


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

Только что, VladislavS сказал:

С чего бы это? Кто так умолчал? 32-битное значение легко может быть частью упакованной структуры.

Тогда у него должен быть модификатор __packed. А у Вас его нет.  :unknw:

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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