什么是Intrinsics?

91

有人能解释一下它们是什么以及我为什么需要它们吗?如果我需要使用内在函数,我要构建何种应用程序?


1
http://en.wikipedia.org/wiki/Intrinsic_function - sellibitze
4个回答

104

内置函数是编译器在可能的情况下直接实现的函数,而不是链接到库提供的函数实现。

一个常见的例子是strncpy()

对于短字符串,调用strncpy()函数需要设置一个'堆栈帧'和返回地址,这将比复制字节本身消耗更多时间。更糟糕的是,对CPU预取缓存的影响会使CPU执行停止数个时钟周期。

相反,编译器会在调用strncpy()的地方直接实现内置函数。在strncpy()的示例中,字节复制代码将直接在该位置发出。

strncpy()示例类似,如果满足所需约束条件,则每个内置函数都直接作为内联代码实现。

非内置函数的内置函数复制通常仍存在于标准库中,以防需要函数的地址。

与内联函数相比,内置函数由编译器提供。在C程序的源代码中没有写入内置函数的位置,也没有必须链接的库实现。内联函数不同之处在于编译器读取内联函数的源代码,但类似于后来它可能直接将编译后的内联函数翻译成目标代码,省略了函数调用的开销。

简而言之,内置函数和内联函数的实际区别在于,即使您没有#include包含函数声明的头文件,内置函数仍将"存在"。对于内联函数,必须先#include包含函数声明的头文件才能使用。


63

通常,“内在函数”是指内置的函数,即大多数标准库函数,编译器可以/将会生成内联代码,而不是调用库中的实际函数。例如,像这样的调用:memset(array1,10,0) 可以被编译为类似以下内容的x86代码:

 mov ecx, 10
 xor eax, eax
 mov edi, offset FLAT:array1
 rep stosb

像这样的内部函数纯粹是为了优化而存在的。 "需要"内部函数的情况很可能是编译器支持内部函数,使您可以生成编译器无法(或通常不会)直接生成的代码。 显而易见的例子是,针对x86的许多编译器具有“MMX Intrinsics”,使您可以使用实际上只是MMX指令的直接表示的“函数”。


13

内置函数是编译器作为函数暴露出来的,不属于任何库。

你最可能会使用的是汇编内置函数,编译器将其视为它们代表的机器指令。例如,在需要利用编译器没有自动生成的特定CPU指令的代码中,并且您不一定需要完整的内联汇编部分时,您可以使用它们。


1
使用情况:SIMD指令集(SSE、Altivec、Neon),编译器很难确定何时使用它们,但是与汇编相比,在C语言编码中仍然可以获得寄存器分配/堆栈帧管理的好处。 - centaurian_slug

4

“Intrinsics”是一门语言中编译器能够识别并自动实现而不需要程序声名的特性。编译器可能会或可能不会链接到运行库来执行操作。例如,在C++中,结构体复制操作是隐式的:

struct {
    int  a;
    char b [100];
    long c [27];
} s, t;

...
s = t;   // this statement copies hundreds of bytes, likely with a rtl call

其他的例子包括Fortran等语言,这些语言有对复杂类型的隐式支持,并且三角函数(如正弦、正切等)不需要声明也无法声明。PHP、Javascript、Ruby等语言有数百个内置函数,例如用于创建和搜索数组,执行正则表达式匹配等等。

至于你的其他问题,唯一的区别就是是否需要声明。例如,使用三角函数的C++程序必须包含数学库声明:

#include <math.h>

没有特别的应用程序模式依赖于内在函数,这只是编译器作者和程序员关注的问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接