Russian Qt Forum
Ноябрь 22, 2024, 14:28 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Каково отличие gcc __attribute__ ((pure)) от ключевого слова const  (Прочитано 12122 раз)
Sancho_s_rancho
Гость
« : Март 19, 2010, 14:05 »

Официальное описание __attribute__ ((pure))
Цитировать
Many functions have no effects except the return value and their return value depends only on the parameters and/or global variables. Such a function can be subject to common subexpression elimination and loop optimization just as an arithmetic operator would be. These functions should be declared with the attribute pure. For example,

          int square (int) __attribute__ ((pure));
     

says that the hypothetical function square is safe to call fewer times than the program says.

Some of common examples of pure functions are strlen or memcmp. Interesting non-pure functions are functions with infinite loops or those depending on volatile memory or other system resource, that may change between two consecutive calls (such as feof in a multithreading environment).

Какая разница между функцией с атрибутом "pure" и  const функцией?
Записан
BRE
Гость
« Ответ #1 : Март 19, 2010, 14:25 »

Какая разница между функцией с атрибутом "pure" и  const функцией?
Атрибут const можно применять только в методам класса. Он говорит о том, что этот метод не изменит состояние объекта, для которого вызывается. Т.е. его можно применять для кнстрантных объектов.
Атрибут pure может применяться и к обычным функциям. Как я понял, позволяя компилятору gcc лучше оптимизировать код. Например, если функция вызывается в цикле и просто возвращает значение не зависящее от параметров цикла, то не обязательно ее вызывать на каждой итерации, а достаточно это сделать один раз перед началом цикла.
Записан
Tonal
Гость
« Ответ #2 : Март 22, 2010, 12:45 »

Добавлю, что const методы могут изменять члены своего объекта объявленные как mutable и используя приведение (const_cast) для снятия константности с this. Кроме того они могут менять внешнее состояние - например глобальные переменные.

Используя атрибут pure, ты гарантируешь компилятору, что функция ничего не меняет вовне. Улыбающийся
Записан
SABROG
Гость
« Ответ #3 : Апрель 22, 2010, 18:01 »

"Pure" (вид функций удовлетворяющих определенным требованиям, а не просто название флага) функции позволяют произвести оптимизацию за счет одного из видов кеширования, в зарубежной литераторе оно называется memoization (мемоизация). Основная идея состоит в том, чтобы не вызывать функцию повторно, если функция гарантирует одно и то же возвращаемое значение на определенные параметры. Если брать приведенный выше пример:

Код
C++ (Qt)
int square (int) __attribute__ ((pure));

Эта функция вычисления корня. Как мы знаем, по меркам процессора, вычисление корня числа - дорогая/затратная/медленная операция. Если мы вычисляем корень из 4, то получаем 2. Сколько бы раз мы не вычисляли корень из четырех у нас всегда будет на выходе - 2. Поэтому руководствуясь методом кеширования (мемоизацией) мы просто сохраняем в некую таблицу - входной параметр и результат. И вместо того, чтобы в следующий раз вызывать вычисление корня над параметром 4 мы просто ищем этот параметр в таблице и возвращаем результат. Если этого параметра в таблице нет, то вызывается оригинальная функция.

Предположим такую задачу. У нас есть массив динамически сгенеренных чисел и мы должны вычислить корень каждого. Пусть это будет элементов, значение числа от 1 до 100. То есть на каждое число приходится "близнец". Функция square() будет вызвана 100 раз, а на остальные 100 элементов будет подставлено уже полученное ранее значение на такой же параметр.

Естественно, что нет никакого смысла применять этот аттрибут над функциями, которые могут выполняться быстрей чем поиск и выборка значения результата из таблицы в памяти. Более того, первичные вызовы функции могут быть намного медленней за счет добавления параметра и возвращаемого значения в таблицу в памяти (кеширования).

Использовать или не использовать зависит от того насколько медленно выполняется функция по сравнению с возможным оверхедом. Кроме того достаточно частые вызовы функции с огромным количеством разных значений может отъесть немало памяти к концу цикла. Можно представить сколько её понадобится, если в функцию будут последовательно передавать 4294967295 значений (размер int), правда в этом случае сам пользователь не дождется завершения программы, но если возвращаемое значение тоже int, то это уже как минимум 8Гб оперативы.
Записан
Tonal
Гость
« Ответ #4 : Апрель 23, 2010, 09:16 »

2 SABROG Меморизация, это конечно хорошо, но результат функции с атрибутом pure может зависить не только от параметров, но и от глобальных переменных.:
Цитировать
Many functions have no effects except the return value and their return value depends only on the parameters and/or global variables.
Из документации.
То о чём ты пишешь это атрибут __attribute__ ((const)).
Т. о. С++ const, __attribute__ ((const)) и __attribute__ ((pure)) несколько отличаются друг от друга. Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Апрель 23, 2010, 12:00 »

Вычисление квадратного корня поддерживалось процессорами еще лет 7 назад - а может и больше. Слабо верится что компилятор будет создавать "таблички" - это довольно накладно и обычно имеет смысл если допустима интерполяция. Я так понимаю
Код
C++ (Qt)
for (i = 0; i < limit; ++i)
 theLen += GetLen(i) + strlen("suffix");
 
Здесь strlen (pure) может быть вызвана 1 раз
Записан
SABROG
Гость
« Ответ #6 : Апрель 23, 2010, 12:38 »

То о чём ты пишешь это атрибут __attribute__ ((const)).

Я бы сказал, что __attribute__ ((const)) частный случай __attribute__ ((pure)). Компилятору известно какие глобальные переменные использует функция, поэтому ему не составит труда провести оптимизацию.
Записан
Tonal
Гость
« Ответ #7 : Апрель 24, 2010, 14:18 »

Раз компилятору и так всё известно, то и атрибуты не нужны. Улыбающийся
Атрибуты то пишутся при объявлении функции - сама функция может быть скомпилирована совершенно другим компилятором, который вовсе ничего об атрибутах не знает. Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.114 секунд. Запросов: 23.