Можно ли форсировать оптимизацию хвостовых вызовов в GCC / Clang? - PullRequest
7 голосов
/ 24 января 2011

Я пытаюсь написать программу в функциональном стиле на C, насколько это возможно. Я знаю, что хорошие компиляторы, такие как GCC / Clang, выполняют оптимизацию хвостовых вызовов без уведомления, но это не гарантируется. Есть ли возможность принудительной оптимизации хвостовых вызовов на компиляторах? (Конечно, когда он вызывается только в самом конце)

Ответы [ 4 ]

6 голосов
/ 24 января 2011

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

1 голос
/ 23 июля 2014

Мета-ответ:

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

Используйте языки в своих сильных сторонах. C подходит для некоторых вещей, так что используйте его для тех, в хорошем стиле C. Если вам нужны разные сильные стороны или вы хотите использовать функциональный стиль (отличное решение!), Используйте функциональный язык.

0 голосов
/ 20 января 2016

Если это действительно хвостовой вызов, тогда цикл while или goto не будут сильно отличаться от рекурсивного вызова. Просто обновите все переменные вместо того, чтобы передавать их в качестве параметров. AFAIK - это единственный кроссплатформенный способ в C контролировать использование стека на всех уровнях оптимизации. На самом деле он также может быть более читабельным, поскольку у вас есть одна функция с инициализацией, за которой следует цикл, что довольно идиоматично. Хвостовая рекурсивная версия требует две функции, одну для инициализации и одну для рекурсивной части.

0 голосов
/ 24 января 2011

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

...