Что делает __, встраивают __ средний?

Я пытаюсь изучить C. Прочитывая некоторый код, я столкнулся со строкой как это:

__inline__ void () ...

Что делает __inline__ средний?. Как делает помещение, что слово перед функцией делает его отличающимся?

32
задан ddpd 19 August 2016 в 09:23
поделиться

5 ответов

Нет. Твое понимание не совсем правильно.

Следующим узлом, который необходимо посетить в случае единообразного поиска затрат, будет D, так как он имеет наименьшую общую стоимость от корня (7, в отличие от 40 + 5 = 45).

Жадный поиск не возвращается к дереву - он выбирает наименьшее значение и фиксирует его. Единые затраты (Uniform Cost) - выбираются самые низкие общие затраты из всего дерева.

-121--1416723-

При единообразном поиске затрат всегда учитываются все неиспользованные узлы, которые вы видели до сих пор, а не только те, которые подключены к рассматриваемому узлу. Итак, в вашем примере, после выбора C, вы обнаружите, что посещение G имеет общую стоимость 40 + 5 = 45, которая выше, чем стоимость начала с корня и посещения D, которая стоит 7. Значит, вы навещаете Д следующим.

-121--1416724-

__ inline __ является нестандартным расширением. Обычно он говорит компилятору: «встроить эту функцию», но будучи нестандартным расширением мы не можем сказать с уверенностью, если не знаем, на каком компиляторе это включено.

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

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

int min(int x, int y)
{
    return (x < y) ? x : y;
}

Если бы я использовал эту функцию в своем коде, это была бы огромная трата времени, чтобы фактически сделать вызов функции, здесь. Если бы у меня было:

int a = /* some calculation */;
int b = /* some other calculation */;

int minCalc = min(a, b);

И компилятор встроил эту функцию, код стал бы:

int a = /* some calculation */;
int b = /* some other calculation */;

int minCalc = (a < b) ? a : b;

Что снимает накладные расходы на вызов функции. Отсюда можно сделать еще больше оптимизаций, когда компилятор получает возможность работать непосредственно с кодом, который обычно скрывался бы за вызовом функции. Как вы видите, если у меня есть большая функция и я заставляю компилятор встроить ее везде, размер кода может расти очень очень быстро, и на самом деле будет препятствовать скорости выполнения.

Существует стандартное ключевое слово inline , которое использовалось для указания компилятору, что функция должна быть встроена, но в настоящее время большинство компиляторов даже не признают ее как подсказку для встраивания функции.

Однако существует важный побочный эффект встроенной , и это может быть полезно. Если функция помечена как встроенная , множественные определения одной и той же функции для нескольких единиц перевода не являются ошибкой. Вместо этого выбирается определение одной функции, а остальные выбрасываются, и предполагается, что они одинаковы (вы должны убедиться, что это на самом деле хорошо!).Это позволяет определить функцию в файле заголовка без риска ошибок нарушения УСО.

39
ответ дан 27 November 2019 в 20:49
поделиться

Функция Wikipedia / Inline

В Компьютерная наука , встроенная функция - это язык программирования , используемая для A компилятор Он должен выполнять встроенное расширение на конкретной функции. Другими словами, компилятор вставит полное тело функции в каждом месте в коде, где используется эта функция.

Руководство GCC § 5.36

Если вы пишете заголовочный файл, который будет включен в программы ISO C89, напишите __ встроенные __ вместо встроенного . Смотреть Альтернативные ключевые слова .

4
ответ дан 27 November 2019 в 20:49
поделиться

Декларация __ __ __ Декларация говорит о компилятору, что везде, где функция будет призвана к «встроенному» функции вместо этого. Включение аналогично использованию макроса - код будет расширен, как будто вы написали все, где вы назвали функцию.

См. Документы GNU для получения дополнительной информации.

1
ответ дан 27 November 2019 в 20:49
поделиться

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

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

7
ответ дан 27 November 2019 в 20:49
поделиться

Существует перегрузка Enumerable.Distinct () , которая занимает IEqualityComparer .

Вот пример, где я использовал его для фильтрации целых чисел по четности:

    class IntParitiyComparer : IEqualityComparer<int>
    {
        public bool Equals(int x, int y)
        {
            return x % 2 == y % 2;
        }

        public int GetHashCode(int obj)
        {
            return obj % 2;
        }
    }

    static void Main(string[] args)
    {
        var x = new int[] { 1, 2, 3, 4 }.Distinct(new IntParitiyComparer());

        foreach (var y in x) Console.WriteLine(y);
    }

Это неуклюже; К будет чище.

-121--3612834-
public static Color ToColor(this uint argb)
{
    return Color.FromArgb((byte)((argb & -16777216) >> 0x18),
                          (byte)((argb & 0xff0000) >> 0x10),
                          (byte)((argb & 0xff00) >> 8),
                          (byte)(argb & 0xff));
}

и используя:

Color c = colorAsInt.ToColor()
-121--3153896-

в основном, это намек компилятору; Предполагается, что там, где используется эта функция, можно вставить код напрямую.

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

бит вуду является наиболее запутанной частью.:) не обязательно полагаться на __ inline __ (или более стандартную inline) для работы; оптимизировать алгоритмы или реорганизовать код, если вы действительно заботитесь о скорости.

0
ответ дан 27 November 2019 в 20:49
поделиться
Другие вопросы по тегам:

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