встраивание кода C: -flto или не -flto

Одна из моих недавних программ сильно зависит от встраивания нескольких «горячих» функций для повышения производительности. Эти горячие функции являются частью внешнего файла .c, который я бы предпочел не менять.

К сожалению, хотя Visual довольно хорош в этом упражнении, gcc и clang — нет. Видимо, из-за того, что горячие функции находятся внутри другого .c, они не могут их инлайнить.

Это оставляет мне 2 варианта:

  • Либо включите непосредственно соответствующий код в целевой файл. На практике это означает #include "perf.c" вместо #include "perf.h". Тривиальное изменение, но выглядит некрасиво. Ясно, что это работает. Просто немного сложнее объяснить цепочке сборки, что perf.c должен быть там, но не компилироваться и не компоноваться.
  • Используйте -flto для оптимизации времени соединения. Это выглядит чище, и это то, чего Visual достигает по умолчанию.

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

    Что касается clang, он просто не работает с -flto из-за ошибки упаковки (ошибка загрузки плагина: LLVMgold.so), которая, по-видимому, очень распространена во многих дистрибутивах Linux.

2 вопроса:

  1. Есть ли способ отключить эти предупреждающие сообщения при использовании -flto в gcc?
  2. Какой из двух методов, описанных выше, кажется лучшим, учитывая плюсы и минусы?
  3. Необязательно: есть ли другое решение?

person Cyan    schedule 05.07.2015    source источник
comment
Обычно файлы, содержащие встроенные функции, получают расширение .inl и #include внизу соответствующего заголовка.   -  person Sneftel    schedule 05.07.2015
comment
В отчете об ошибке говорится, что она была исправлена. Есть ли возможность попробовать последнюю версию binutils?   -  person P.P    schedule 05.07.2015
comment
Пожалуйста, укажите версии инструментов.   -  person too honest for this site    schedule 05.07.2015
comment
@blueMoon: не совсем так. Разрешить ситуацию только для меня не вариант. Это должно работать для других команд с другими цепочками сборки, которые я не контролирую, поэтому невозможно зависеть от слишком конкретной версии. Кроме того, есть еще пб лязг...   -  person Cyan    schedule 05.07.2015
comment
@olaf: я тестировал gcc 4.8.4 и clang 3.4. Но, как сказано в предыдущем комментарии, мне нужно поддерживать более широкие конфигурации.   -  person Cyan    schedule 05.07.2015
comment
Конфигурации Borader не обязательно включают старые версии компилятора. Попробуйте LTO с 4.7.2, и вы тоже столкнетесь с проблемами. Где-то вам в конечном итоге придется сделать разрез. Обратите внимание, однако я спросил об инструментах, а не только о компиляторах. Как насчет бинутилса? Обратите внимание, что LTO требует запуска этапа компоновки точно с теми же параметрами, что и при компиляции. Также для правильной компиляции требуется, чтобы все части были LTO-ed. Не уверен насчет stdlib из стандартной установки (обычно это динамически компонуется).   -  person too honest for this site    schedule 05.07.2015
comment
Я почти уверен, что мне придется поддерживать gcc 4.4, clang 3.2 и visual 2010. Может быть, даже старше. Если у меня возникнут проблемы с настройкой правильной конфигурации, то для моих пользователей будет еще хуже. Я не собираюсь играть со странными конфигами и говорить своим пользователям делать что-то, что может нарушить работу их системы. Либо его можно безопасно встроить и автоматизировать в Makefile, либо это не годится. Исходя из этих предпосылок, ответ @Sneftel выглядит ближе к истине.   -  person Cyan    schedule 05.07.2015
comment
В зависимости от размера проекта вы также можете использовать сборку объединения для сборок выпуска, аналогичную тому, что делает sqlite.   -  person technosaurus    schedule 05.07.2015


Ответы (1)


Согласно вашему комментарию, вы должны поддерживать gcc 4.4. Поскольку LTO начинался с gcc 4.5 (со всей осторожностью в отношении ранних версий), ответ должен быть однозначным. нет -flto.

Итак, #include код со всей осторожностью, конечно.

Обновлять:

Однако расширение файла не должно быть .c, а, например, .inc (.i тоже плохая идея). Еще лучше: .h и измените функции на static inline. Это по-прежнему может не гарантировать встраивания, но это то же самое, что и для всех функций, и он поддерживает внешний вид чистого заголовка (хотя более длинная функция inline по-прежнему является плохим стилем).

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

person too honest for this site    schedule 05.07.2015