Будет ли GCC встроить функцию, которая принимает указатель?

У меня есть функция, которая работает с куском данных (скажем, int), и я хочу изменить его на месте, передав ссылку на valule. Таким образом, у меня есть функция: void myFunction(int *thing) { ... }. Когда я его использую, я называю это следующим образом: myFunction(&anInt).

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

Будет ли компилятор иметь возможность оптимизировать функцию, вставляя ее для работы непосредственно с моей переменной anInt?

Надеюсь, вы ответите на этот вопрос в духе, в котором он спросил (т.е. я преждевременно не беспокоюсь об оптимизации, мне любопытно ответить). Точно так же я не хочу превращать его в макрос.

Ответы

Ответ 1

GCC довольно умный. Рассмотрим этот фрагмент кода:

#include <stdio.h>

void __inline__ inc(int *val)
{
    ++ *val;
}

int main()
{
    int val;

    scanf("%d", &val);

    inc(&val);

    printf("%d\n", val);

    return 0;
}

После gcc -S -O3 test.c вы получите следующее соответствующее asm:

...
call    __isoc99_scanf
movl    12(%rsp), %esi
movl    $.LC1, %edi
xorl    %eax, %eax
addl    $1, %esi
movl    %esi, 12(%rsp)
call    printf
...

Как вы можете видеть, нет необходимости быть экспертом asm, чтобы увидеть, как вызов inc() был преобразован в инструкцию приращения.

Ответ 2

Один из способов выяснить, включена ли функция, - использовать опцию -Winline gcc:

-Winline
  Warn if a function can not be inlined and it was declared as inline.
  Even with this option, the compiler will not warn about failures to inline
  functions declared in system headers.

  The compiler uses a variety of heuristics to determine whether or not to
  inline a function. For example, the compiler takes into account the size
  of the function being inlined and the amount of inlining that has already
  been done in the current function.  Therefore, seemingly insignificant
  changes in the source program can cause the warnings produced by -Winline
  to appear or disappear.

Ответ 3

Здесь есть два вопроса: можно ли оптимизировать код и будет ли он. Это, безусловно, может быть, но "воля" зависит от настроения, в котором работает оптимизатор. Если это действительно важно для вас, скомпилируйте код и посмотрите на выход ассемблера.

Кроме того, похоже, вы сталкиваетесь с двумя проблемами. Встроенная функция эффективно имеет свое тело, вставленное на сайт вызова. Независимо от того, используете ли вы указатели, ни здесь, ни там. Но вы, кажется, спрашиваете, может ли компилятор преобразовать:

int x = 42;
int * p = & x;
* p = * p + 1;

в

x = x + 1;

Это гораздо труднее для оптимизатора.

Ответ 4

Не имеет значения, является ли аргумент указателем или нет.

Но сначала, если компилятор должен автоматически встроить функцию, она должна быть статичной. И он должен содержаться в одной и той же компиляционной единице. ПРИМЕЧАНИЕ: мы говорим о C, а не С++. Стандартные правила С++ различаются.

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

C99 дает вам ключевое слово "inline", как и на С++. Который отменяет ограничение на блок компиляции.

Ниже приведена дополнительная информация.

Ответ 5

Он будет (или, по крайней мере, может). Есть некоторые причины, по которым функция не может быть встроена - например. когда вы пытаетесь получить доступ к указателю функции (вызывающая функция по ссылке - вы получаете доступ к параметрам по ссылке, которая в порядке). Может быть другая ситуация (статические переменные? Unsure)

Попробуйте объявить функцию с помощью "extern inline" - это не позволяет компилятору испускать автономный объект. Если он не может встроить функцию, он выдаст ошибку.

Ответ 6

Если вы обеспокоены компилятором, генерирующим субоптимальный код и хотите изменить простой тип valuetype, объявите свою функцию как int myFunction(int) и верните новое значение.

Ответ 7

Какую версию компилятора вы используете? С какими вариантами? На какой платформе?

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

Ответ 8

Это выглядит как классический случай преждевременной оптимизации. Вы действительно знаете, что здесь есть проблема с производительностью? Стоит тратить драгоценное время на беспокойство. Я имею в виду, действительно знаю? Например, вы это измерили?

Само по себе это не так уж плохо, но если вы придерживаетесь такого отношения к большому количеству кода, вы можете нанести серьезный урон и отбросить большое количество девелопмента и времени обслуживания без уважительной причины.