|
|
  |
Оптимизация встраивания функций, для чистых функций |
|
|
|
Dec 21 2010, 07:43
|
Местный
  
Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123

|
Доброго всем времени суток.
Имеется чистая функция - принимает один целочисленный параметр и возвращает результат, который зависит только от этого параметра. Никаких побочных эффектов - казалось-бы идеальный кандидат для встраивания. В большинстве случаев в эту функцию передаются константные параметры и редко переменные. Хочется, чтобы при передаче константного параметра, функция встраивалась и выполнялась константная подстановка (вызов функции заменялся вычисленным во время компиляции значением), а при передачи переменной происходил честный вызов функции. Компиляторы семейства GCC именно так и делают. Компиляторы IAR ведут себя по другому: если функция вызывается с константными параметрами больше определённого порогового числа раз, то компилятор генерирует тело этой функции и перестаёт её встраивать везде, даже где это выгодно. #pragma inline=forced помогает не сильно, так как функция встраивается всегда, в том числе при переменных аргументах, когда это не выгодно. Иными словами, функция или всегда встраивается, или всегда вызывается. GCC, как я уже говорил принимает решение о встраивании функции для каждого ее упоминаия в исходном тексте.
Кто-нибудь знает как добиться желаемого поведения от компиляторов IAR?
Всё описанное справедливо, вероятно, для всех компиляторов семейства IAR. По крайней мере, для платформ ARM, AVR & MSP430.
|
|
|
|
|
Dec 21 2010, 08:33
|

Гуру
     
Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237

|
Цитата(vmp @ Dec 21 2010, 14:17)  А если функцию описать как static, чтобы компилятор знал, что это локальная функция и из других файлов вызываться не будет? Это не поможет. Компилятор не обязан вычислять значения функций. Например, даже если вы запишите sin(0.5), то не ожидайте, что компилятор станет вычислять синус в момент компиляции. Функция, она функция и есть. Вычисления над константами в момент компиляции касаются лишь элементарных операций, как-то - арифметических и логических операций, но отнюдь не вычислений функций в выражениях. А если вам нужно, чтобы тело функции вычислялось в момент компиляции, тогда используйте не функцию, а дефайн. Например так: Код #define func(x) 2*(x)*(x)+4*(x)-6 тогда это действительно будет всегда прямая подстановка, и если x окажется константой, то компилятор вычислит всё выражение func во время компиляции.
|
|
|
|
|
Dec 21 2010, 08:48
|

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

|
Цитата(MrYuran @ Dec 21 2010, 14:20)  То есть, вы хотите, чтобы одна и та же функция либо встраивалась, либо нет в зависимости от контекста? А почему бы и нет? Цитата(Xenia @ Dec 21 2010, 14:33)  Это не поможет. Компилятор не обязан вычислять значения функций. Например, даже если вы запишите sin(0.5), то не ожидайте, что компилятор станет вычислять синус в момент компилляции. Функция, он функция и есть. Это можно ожидать. Многие компиляторы так давненько поступают. Это из оперы: http://en.wikipedia.org/wiki/Constant_folding
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Dec 21 2010, 09:06
|
Местный
  
Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123

|
Цитата(Xenia @ Dec 21 2010, 14:33)  А если вам нужно, чтобы тело функции вычислялось в момент компиляции, тогда используйте не функцию, а дефайн. Например так:
#define func(x) 2*(x)*(x)+4*(x)-6
тогда это действительно будет всегда прямая подстановка, и если x окажется константой, то компилятор вычислит всё выражение func во время компиляции. Нет, дефайн даст тот-же результат, что и функция + #pragma inline=forced. Только функция в данном случае всё равно лучше. Цитата(Xenia @ Dec 21 2010, 14:57)  А не факт, что IAR того же не умеет. Многое зависит от установок оптимизации, тогда как топикстартер молчит об этих установках, как рыб  . Различные установки оптимизации не дают желаемого результата - функция либо всегда встраивается, либо всегда нет, не зависимо от контекста её вызова.
|
|
|
|
|
Dec 21 2010, 17:23
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(Сергей Борщ @ Dec 21 2010, 17:37)  Напишите две идентичные функции С учетом золотого правила, что одинаковых последовательностей команд не должно быть, этот совет должен звучать как - напишите макрос и вставьте макрос в тело функции. Для констант вызывайте макрос, для переменных функцию. Всего то запомнить- вводи все на одинаковом регистре. Цитата(Xenia @ Dec 21 2010, 14:57)  ... тогда как топикстартер молчит об этих установках... Кстати да. Зачем то ИАР сделал выбор оптимизации по скорости/размеру/баланс. Дык какой режим тестировал топикстартер? А?!
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Dec 22 2010, 00:21
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(scifi @ Dec 22 2010, 00:56)  зачем пытаться заставить компилятор генерить код с узко-специальной ... Ну, тут вопрос вполне адекватен, касается поведения компилятора при задании высокого уровня оптимизации. Я тоже рассчитываю на определенное упрощения кода при оптимизации и тоже портирую между IAR и GCC. Правда, не рассчитываю на расчет функций на этапе компиляции. Мечтам нужно подрезать крылья
--------------------
Уходя, оставьте свет...
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|