Можно ли выполнить все оптимизации времени компиляции с оптимизацией времени компоновки?

Или есть некоторые оптимизации, которые можно выполнить только во время компиляции (и, следовательно, работать только в единицах компиляции)? Я спрашиваю, потому что в C единицей компиляции является исходный файл, и я пытаюсь понять, есть ли какая-либо причина не разбивать исходный код на отдельные файлы в некоторых обстоятельствах (например, оптимизация, которую можно было бы сделать, если бы весь исходный код были в одном файле не делалось).


person awelkie    schedule 24.02.2015    source источник
comment
Ничего себе - весь код за один раз - я бы не хотел быть парнем, который следует за вами, который должен поддерживать это..   -  person Nim    schedule 24.02.2015
comment
Как оптимизация времени компоновки справится с сокращением кода внутри функции? Может я не понял вопроса...   -  person Scott Hunter    schedule 24.02.2015
comment
Да, LTO был введен, чтобы включить все оптимизации без необходимости компилировать все за один раз из исходников (независимо от нескольких TU одновременно или всех TU).   -  person Deduplicator    schedule 24.02.2015
comment
@Nim, весь код в одном файле :)   -  person David Ranieri    schedule 24.02.2015
comment
Если бы было какое-то преимущество в том, чтобы поместить все в одну единицу перевода, это было бы исправлено разработчиками компилятора из опасения, что программисты начнут его использовать.   -  person Sergey Kalinichenko    schedule 24.02.2015
comment
Я не говорю обо всем исходном коде программы. Мне просто интересно, есть ли какие-либо обстоятельства, при которых разделение некоторого кода на несколько файлов может привести к снижению производительности. Это действительно просто мое любопытство.   -  person awelkie    schedule 24.02.2015
comment
@DurnWhippersnapper Как и в случае со многими вопросами, связанными с программированием, в форме Есть ли какие-либо обстоятельства, при которых выполнение X приведёт к снижению производительности?, ответ таков: вероятно буквально, да; практически нет. Всегда будут патологические случаи, которые вы, вероятно, сможете придумать, но это не значит, что вам следует беспокоиться о них.   -  person MooseBoys    schedule 24.02.2015
comment
@AlterMann, Эба, Генау.. ;)   -  person Nim    schedule 24.02.2015


Ответы (2)


Типичная (упрощенная) компиляция может выглядеть так:

1) Pre-process
2) Parse code to internal representation
3) Optimize code
4) Emit assembly language
5) Assemble to .o file
6) Link .o file to a.out 

LTO обычно достигаются путем сброса внутреннего представления компилятора на диск между шагами 2 и 3, а затем во время последней ссылки (шаг 6) возвращаются и выполняют шаги 3-5. Однако это может зависеть от компилятора и версии. Если он будет следовать этому шаблону, вы увидите LTO, эквивалентный оптимизации времени компиляции.

Тем не мение ...

Наличие очень больших исходных файлов может раздражать — Emacs начинает задыхаться от исходных файлов >10 МБ.

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

Если вы используете распределенную систему сборки, вы выполняете параллельную компиляцию. Таким образом, если для компиляции и оптимизации файла требуется 1 секунда, и у вас есть 1000 файлов и 1000 агентов сборки, общее время компиляции составляет 1 секунду. Если вы делаете всю свою оптимизацию для всех 1000 файлов во время финала, у вас будет 999 агентов, которые будут простаивать, а 1 агент потратит целую вечность на всю вашу оптимизацию.

person Andrew C    schedule 24.02.2015

академический пример:

main()
{
  int i;
  for (i = 0; i < MAX; i++) {
    fun(i);
  }
}

fun(int i)
{
  if (i == 0) {
    doSomething();
  }
}

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

НО: я бы остался с комментарием MooseBoys.

person Peter Miehle    schedule 24.02.2015