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

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

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

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

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

14
задан Joe 7 January 2010 в 15:03
поделиться

8 ответов

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() преобразован в инкрементную инструкцию.

.
9
ответ дан 1 December 2019 в 07:39
поделиться

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

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

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

в

x = x + 1;

Это гораздо сложнее увидеть оптимизатору.

.
7
ответ дан 1 December 2019 в 07:39
поделиться

По мне, так это классический случай преждевременной оптимизации. Знаете ли вы на самом деле , что здесь есть проблема с производительностью? Одна из них стоит того, чтобы тратить ваше драгоценное время на беспокойство. Я имею в виду, действительно знаете ? Типа, вы его измеряли?

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

-1
ответ дан 1 December 2019 в 07:39
поделиться

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

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

-1
ответ дан 1 December 2019 в 07:39
поделиться

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

0
ответ дан 1 December 2019 в 07:39
поделиться

Один из способов узнать, включена ли функция, - использовать -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.
18
ответ дан 1 December 2019 в 07:39
поделиться

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

Постарайтесь объявить функцию с помощью «Extern Inline» - это предотвращает выделение компилятора автономного корпуса. Если он не может встроить функцию, она выделяет ошибку.

1
ответ дан 1 December 2019 в 07:39
поделиться

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

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

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

C99 дает вам ключевое слово «Inline», как и в C ++. Который поднимает ограничение к блоку компиляции.

Вот некоторые дополнительная информация .

2
ответ дан 1 December 2019 в 07:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: