В компьютерном программном обеспечении , в теории компиляторов, внутренняя функция , также называемая встроенной функцией или встроенной функцией , — это функция ( подпрограмма ), доступная для использования в данном языке программирования , реализация которой обрабатывается компилятором специально . Как правило, она может заменять последовательность автоматически сгенерированных инструкций для исходного вызова функции, аналогично встроенной функции . [1] В отличие от встроенной функции, компилятор имеет глубокие знания о встроенной функции и, таким образом, может лучше интегрировать и оптимизировать ее для данной ситуации.
Компиляторы, реализующие встроенные функции, могут включать их только тогда, когда программа запрашивает оптимизацию , в противном случае возвращается к реализации по умолчанию, предоставляемой системой выполнения языка (средой).
Встроенные функции часто используются для явной реализации векторизации и параллелизации в языках, которые не рассматривают такие конструкции. Некоторые интерфейсы прикладного программирования (API), например, AltiVec и OpenMP , используют встроенные функции для объявления, соответственно, векторизуемых и многопроцессорных операций во время компиляции. Компилятор анализирует встроенные функции и преобразует их в векторную математику или многопроцессорный объектный код, подходящий для целевой платформы . Некоторые встроенные функции используются для предоставления дополнительных ограничений оптимизатору, таких как значения, которые переменная не может принимать. [2]
Компиляторы для C и C++ от Microsoft, [3] Intel, [1] и GNU Compiler Collection (GCC) [4] реализуют встроенные функции, которые напрямую сопоставляются с инструкциями x86 single instruction, multiple data ( SIMD ) ( MMX , Streaming SIMD Extensions (SSE), SSE2 , SSE3 , SSSE3 , SSE4 , AVX , AVX2 , AVX512 , FMA , ...). Компилятор Microsoft Visual C++ из Microsoft Visual Studio не поддерживает встроенный ассемблер для x86-64 . [5] [6] [7] [8] Чтобы компенсировать это, были добавлены новые встроенные функции, которые сопоставляются со стандартными инструкциями ассемблера, которые обычно недоступны через C/C++, например, побитовое сканирование.
Некоторые компиляторы C и C++ предоставляют непереносимые платформенно-зависимые встроенные функции. Другие встроенные функции (например, встроенные функции GNU ) немного более абстрактны, приближаясь к возможностям нескольких современных платформ, с переносимыми резервными реализациями на платформах без соответствующих инструкций. [9] Для библиотек C++, таких как glm или библиотеки векторной математики Sony , [10] характерно достижение переносимости посредством условной компиляции (на основе флагов компилятора, специфичных для платформы), предоставляя полностью переносимые высокоуровневые примитивы (например, четырехэлементный векторный тип с плавающей точкой), отображаемые на соответствующие реализации низкоуровневого языка программирования , при этом по-прежнему используя систему типов C++ и встраивание; отсюда и преимущество перед связыванием с рукописными объектными файлами сборки с использованием двоичного интерфейса приложения C (ABI).
uint64_t __rdtsc (); // возвращает внутренний счетчик часов ЦП uint64_t __popcnt64 ( uint64_t n ); // количество бит, установленных в n uint64_t _umul128 ( uint64_t Factor1 , uint64_t Factor2 , uint64_t * HighProduct ); // 64 бит * 64 бит => 128 бит умножение __m512 _mm512_add_ps ( __m512 a , __m512 b ); // вычисляет a + b для двух векторов из 16 чисел с плавающей точкой __m512 _mm512_fmadd_ps ( __m512 a , __m512 b , __m512 c ); // вычисляет a*b + c для трех векторов из 16 чисел с плавающей точкой
[11]
Компилятор JIT виртуальной машины Java HotSpot (JVM) также имеет встроенные функции для определенных API Java. [12] Встроенные функции Hotspot — это стандартные API Java, которые могут иметь одну или несколько оптимизированных реализаций на некоторых платформах.
ANSI/ISO PL/I определяет около 90 встроенных функций. [13] Они условно сгруппированы следующим образом: [14] : 337–338
Отдельные компиляторы добавляют дополнительные встроенные функции, специфичные для архитектуры машины или операционной системы.
Встроенная функция идентифицируется, если оставить ее имя необъявленным и разрешить ей значение по умолчанию, или если объявить ее BUILTIN
. Пользовательскую функцию с тем же именем можно заменить, объявив ее как ENTRY
.
Встроенные функции
{{cite book}}
: CS1 maint: числовые имена: список авторов ( ссылка )