|
|
  |
Keil, оптимизация математики, почему так и что делать? |
|
|
|
Apr 29 2011, 08:32
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Опции компиляции: Код --feedback ".\obj\xxxx.fed" -c --cpu Cortex-M3 -D__MICROLIB -g -O3 -Otime --apcs=interwork --split_sections --asm --interleave --C99 --asm --interleave -I "C:\Keil\\ARM\INC" -I Пример: Код float func(float x) { return (x*pow(0.1, 0.01)); } Этот негодяй прилинковывает функцию pow и по ходу дела считает её в рантайме, а не на этапе компиляции. С gcc таких сюрпризов не припоминаю. Есть идеи куда копать?
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Apr 29 2011, 09:22
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(demiurg_spb @ Apr 29 2011, 12:32)  Этот негодяй прилинковывает функцию pow и по ходу дела считает её в рантайме, а не на этапе компиляции. С более чем 10 годами опыта программирования на Си я всегда считал, что иначе и быть не может. Цитата(demiurg_spb @ Apr 29 2011, 12:32)  С gcc таких сюрпризов не припоминаю. GCC вычисляет это на этапе компиляции? Если это правда, моё мнение о GCC резко улучшается :-) Цитата(demiurg_spb @ Apr 29 2011, 12:32)  Есть идеи куда копать? Конечно. return x * 0.97723722f;
|
|
|
|
|
Apr 29 2011, 10:39
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(scifi @ Apr 29 2011, 13:22)  С более чем 10 годами опыта программирования на Си... Ну мы с Вами по этому параметру близнецы братья:-), но я по большей части всё это время сидел под GCC. Цитата GCC вычисляет это на этапе компиляции? Если это правда, моё мнение о GCC резко улучшается :-) А что тут странного? constant propagation - уже сто лет в обед. Цитата return x * 0.97723722f; Так и сделано сейчас, но это не удобно, т.к. это число должно зависеть от задефайненого значения. Некрасиво.... (грубо это коэффициент фильтра, зависящий от ADC_SMP_RATE, который должен пересчитываться на этапе компиляции. а ADC_SMP_RATE - любое целое положительное число>0)
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Apr 29 2011, 12:22
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(demiurg_spb @ Apr 29 2011, 14:39)  constant propagation - уже сто лет в обед. Обычно constant propagation ничего не знает про функции. А gcc постарался - молодцы. Цитата(demiurg_spb @ Apr 29 2011, 14:39)  Так и сделано сейчас, но это не удобно, т.к. это число должно зависеть от задефайненого значения. Некрасиво.... (грубо это коэффициент фильтра, зависящий от ADC_SMP_RATE, который должен пересчитываться на этапе компиляции. а ADC_SMP_RATE - любое целое положительное число>0) Ну, можно прикрутить костыль: assert(проверить, что значения двух констант согласованы). Тогда если изменили одну константу, но забыли подправить другую, это вылезет на этапе отладки. Другие варианты тоже так себе: внешний скрипт для генерации констант, инициализация константы в ОЗУ при старте программы.
|
|
|
|
|
Apr 29 2011, 14:23
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(ViKo @ Apr 29 2011, 17:32)  А вот assert как раз работает на этапе run-time, нет? Да. Но когда определён макрос NDEBUG, как это полагается делать при сборке окончательной версии, все assert() пропадают. Цитата(ViKo @ Apr 29 2011, 17:32)  А проверять при компиляции - только #if ... #error. Правильно? Нет, не только. Ещё assert_static(). Только возведение дробных чисел в дробную степень на стадии компиляции - это проблема.
|
|
|
|
|
Apr 29 2011, 23:05
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(DevL @ Apr 30 2011, 00:36)  pow это конечно другое , но было бы интересно пример с constant propagation Просто pow() у него built-in, если это не отбить ключами -fno-builtin или -fno-builtin-pow http://gcc.gnu.org/onlinedocs/gcc-4.6.0/gc...#Other-BuiltinsА на built-in функции constant propagation распространяется естественнейшим образом. Цитата(demiurg_spb @ Apr 29 2011, 11:32)  --cpu Cortex-M3 ... Есть идеи куда копать? В сторону Klen-овой сборки arm-gcc ?
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Apr 30 2011, 08:27
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(prottoss @ Apr 29 2011, 18:40)  А если попробовать сделать так: Код static float pow_01_001(void)... Попробовал - нет разницы. Цитата(scifi @ Apr 29 2011, 18:23)  Нет, не только. Ещё assert_static(). Я STATIC_ASSERT(...) регулярно применяю, и в этом случае тоже пришлось. Может кому пригодится: CODE /* * ASSERTION - УТВЕРЖДЕНИЕ * * Example of usage: * STATIC_ASSERT(sizeof(int) > 4); // produce error in ARM or X86 machine * */
#ifndef _STATIC_ASSERT_H_ #define _STATIC_ASSERT_H_
#ifdef __cplusplus template<bool> struct CompileTimeError; template<> struct CompileTimeError<true> {}; # define STATIC_ASSERT(expr) (CompileTimeError<(expr) != 0>()) #else # define MY_JOIN_3_H(A,B,C) A##B##C # define MY_JOIN_3(A,B,C) MY_JOIN_3_H(A,B,C) # define STATIC_ASSERT_H(expr) typedef int MY_JOIN_3(static_assert_,__LINE__,_h) [(expr) ? 1 : -1] # define STATIC_ASSERT(expr) STATIC_ASSERT_H(expr) #endif
#endif //_STATIC_ASSERT_H_
Цитата(ReAl @ Apr 30 2011, 03:05)  В сторону Klen-овой сборки arm-gcc ?  Я бы и рад, но на новом месте работы keil и баста  2 DevL: Да, шаблоны - вещь приятная и полезная, но проект без плюсов...
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|