gcc C++中的__builtin__函数是什么?

xqnpmsa8  于 2023-08-06  发布在  其他
关注(0)|答案(3)|浏览(231)

我正在调试一个对性能敏感的事务处理系统。
我发现一个代码使用了__builtin_memcpy和__builtin_memset,而不是memcpy和memset。
__builtin_函数有何用途?,以防止对架构或编译器的依赖性问题?
或者...是否有任何性能方面的原因,其中__builtin_functions是首选的?
谢谢:D

kyks70gy

kyks70gy1#

传统的库函数,标准的memcpy只是一个函数的调用。不幸的是,memcpy经常为每个小副本调用,调用函数, Shuffle 几个字节和返回的开销相当大(特别是因为memcpy在函数的开头添加了额外的东西来处理未对齐的内存,循环的展开等,以便在大型副本上做得很好)。
因此,为了让编译器优化这些,它需要“知道”如何做,例如memcpy-解决方案是在编译器中“内置”一个函数,然后包含这样的代码:

int generate_builtin_memcpy(expr arg1, expr arg2, expr size)
 {
     if (is_constant(size) && eval(size) < SOME_NUMBER)
     {
        ... do magic inline memory copy ... 
     }
     else
     {
         ... call "real" memcpy ... 
     }
 }

字符串
[For可重定向的编译器,通常每个CPU架构都有一个这样的函数,它具有不同的配置,例如“真实的的”memcpy被调用的条件,或者何时使用内联memcpy。
这里的关键是,你可以编写自己的memcpy函数,它不是基于__builtin_memcpy(),它总是一个函数,并且不做与普通memcpy相同的事情[如果你经常改变它的行为,你会有点麻烦,因为C标准库可能在几千个地方调用memcpy-但是例如统计memcpy被调用的次数,以及副本的大小可以是一个这样的用例]。
使用__builtin_*的另一个重要原因是,它们提供了一些代码,否则这些代码必须用内联汇编程序编写,或者程序员根本无法使用这些代码。设置/获取特殊寄存器将是这样一件事。
还有其他技术来解决这个问题,例如clang有一个LibraryPass,它假设库调用与其他替代方案执行共同的功能,例如由于printfputs“重”得多,它将合适的printf("constant string with no formatting\n")替换为puts("constant string with no formatting")。并且当用常数等调用时,许多三角函数和其它数学函数被解析为常见的简单值。
直接调用__builtin_*来实现memcpysin之类的函数可能是错误的--这只会降低代码的可移植性,而且根本不一定会更快。在没有其他函数的情况下调用__builtin_special_function通常是一些棘手情况下的解决方案-但您可能应该将其 Package 在自己的函数中,例如。

int get_magic_property()
{
    return __builtin_get_magic_property(); 
}


这样,当您移植到Windows时,您可以轻松地执行以下操作:

int get_magic_property()
{
#if WIN32
    return Win32GetMagicPropertyEx();
#else
    return __builtin_magic_property();
#endif
}

7y4bm7vi

7y4bm7vi2#

__builtin_*函数是由编译器库提供的优化函数。这些可能是标准库函数的内置版本,比如memcpy,也许更典型的是一些数学函数。
或者,它们可能是针对特定目标的典型任务的高度优化的函数-例如DSP可能具有内置FFT函数
哪些函数作为__builtin_提供由编译器的开发人员决定,并将记录在编译器的手册中。
不同的CPU类型和编译器是为不同的用例设计的,这将反映在提供的内置函数范围中。
内置函数可能会利用目标处理器中的专用指令,或者可能会通过使用查找表而不是直接计算值来权衡精度和速度,或者任何其他合理的优化,所有这些都应该记录在案。
这些绝对不是为了减少对特定编译器或cpu的依赖,事实上恰恰相反。它实际上添加了一个依赖项,因此这些可能会被封装在预处理器检查中,例如

#ifdef SOME_CPU_FLAG
#define MEMCPY __builtin_memcpy
#else 
#define MEMCPY memcpy

字符串

b4qexyjb

b4qexyjb3#

编译器注意,__builtin_memcpy可以回退到发出memcpy函数调用。能力较弱的编译器也能够通过选择无条件发出memcpy调用的慢速路径来简化。
http://lwn.net/Articles/29183/

相关问题