Цитата: mrt789 от 05.02.2022 00:18:39Любой же реальный софт основан на вызове подпрограмм и ветвлении, то есть на переходе к тому или иному адресу. Это базовый принцип построения софта - разбиение его на повторно используемые блоки инструкций и переход на них (от функций пользовательских библиотек и до системных вызов ядра ОС - это все адреса для перехода). И да, заинлайнить системный вызов на этапе компиляции не получится, да и с библиотеками линковка обычно идет не статичная.
По первому выделению:
В отношении ветвления программы бывают очень разные. Где-то много циклов, как в вычислительных алгоритмах, и данные тут, в основном, с плавающей запятой, где-то циклов мало, зато куча условных переходов. И в каждом случае требуется разная стратегия оптимизации и параллелизации, если это возможно. Вряд ли в кремнии можно реализовать то, что можно реализовать на уровне компиляции – банально площади не хватит. Горизонт планирования у кремния крайне мал, а вот программист, что касается циклов, знает еще на этапе программирования, где у него что, как и сколько будет крутиться, даже в случае алгоритмов с выходом из цикла по результату, а не по счетчику. Просто необходимо дать ему возможность сообщать компилятору об этом. Если речь идет о C, то стандарт предусматривает механизм такого общения – прагмы (если речь идет об уровне процессора, то, например в случае x86_64, предусмотрены префиксы, которыми программист может влиять на предсказание вероятности переходов).
И еще – если передача параметров в процедуры идет мимо памяти, т.е через регистры, потерь на вызовы можно избежать, имея два кеша инструкций, инструкции по заполнению которых генерируются компилятором, а не кремнием.
А если еще предусмотреть совместную компиляцию как циклов, так и процедур, которые в них крутятся, то даже объявлять их встраиваемыми (inline) не потребуется – компилятор просто встроит код в тело наиболее оптимальным образом. Кремний этого не сможет никогда.
В идеале нужно использовать несколько специализированных процессоров, код на которые будет раскладывать компилятор.
По второму выделению:
С библиотеками в программах-числодробилках линковка обычно идет как раз статическая, что дает прирост в производительности иногда до 30%, а в ряде случаев и в разы (собственный опыт в отношении использования libm). Динамическая линковка катастрофически отнимает у программы память – даже если вы используете всего одну функцию из динамической библиотеки, динамический компоновщик отобразит в ваше адресное пространство всю библиотеку целиком – он не умеет "выдирать" только тот код, который нужен программе, поскольку ничего не знает об этом и нет механизмов об этом ему сообщить. А в случае статической компоновки в вашем адресном пространстве окажется только та часть библиотеки, которая будет реально использоваться.