繁体   English   中英

glibc使用内核函数

[英]glibc uses kernel functions

我试图从glibc源代码中了解此方法:

    26 #if LIBM_SVID_COMPAT
    27 /* wrapper sqrtf */
    28 float
    29 __sqrtf (float x)
    30 {
    31   if (__builtin_expect (isless (x, 0.0f), 0) && _LIB_VERSION     != _IEEE_)
    32     return __kernel_standard_f (x, x, 126); /*    sqrt(negative) */
    33 
    34   return __ieee754_sqrtf (x);
    35 }
    36 libm_alias_float (__sqrt, sqrt)
    37 #endif

据我了解,如果程序无法从glibc中找到sqrt函数的有效实现,它将从内核调用硬件函数,即特定的机器函数。 这是正确的吗?
另外, libm_alias_float (__sqrt, sqrt)是什么意思?

GNU C库的数学功能在“ glibc”源代码树中完全实现。 他们什么都不依赖操作系统内核。 在此上下文中,“内核”一词指的是计算内核,这是某些数学算法的核心,您可能想用手工优化的汇编语言编写该部分。

函数__kernel_standard_f被错误命名。 它包含用于处理数学函数错误的通用代码。 最好将其命名为__math_domain_error 在这种情况下,当__sqrtf的参数为负数时, __sqrtf调用__kernel_standard_f __kernel_standard_f然后将把errnoEDOM ,可能会调用SVID matherr回调,并返回NaN。 (神秘代码126告诉__kernel_standard_f该函数调用它,为什么。的执行__kernel_standard_fsysdeps/ieee754/k_standardf.csysdeps/ieee754/k_standard.c 。)

条件_LIB_VERSION != _IEEE_与是否启用POSIX和/或SVID数学错误处理有关; 现代数学算法实际上只希望在结果中查找NaN,而没有浪费库时间设置errno或调用matherr ,因此有一种机制可以将后两者关闭。

如果__sqrtf的参数不是负数,则尾部将调用__ieee754_sqrtf ,它执行平方根的实际计算。 glibc源代码树中有此功能的几种替代实现。 其仅C的通用版本在sysdeps/ieee754/flt-32/e_sqrtf.c (即使按照glibc的标准,实现数学功能的文件的名称也是神秘的。我不必费心去理解它们,我只是find sysdeps -name '*sqrtf*'或其他名称。)此功能以逻辑开始检测一个负参数(也为零,无穷大和NaN)并返回适当的值,但它不会碰到errno 如果您想了解用于计算平方根的数学技术,请查看此文件。

如果您自己运行上述find命令,则会发现其他几个名为e_sqrtf.c文件; 这些都在以特定CPU命名的目录中,这些CPU的浮点单元对计算平方根具有硬件支持,因此sysdeps/x86_64/fpu/e_sqrt.c读取

double
__ieee754_sqrt (double x)
{
  double res;

  asm ("sqrtsd %1, %0" : "=x" (res) : "xm" (x));

  return res;
}

因为x86 sqrtsd指令可以完成全部工作。

当为其中一个CPU进行构建时,Glibc的构建过程将选择这些文件之一,而不是通用C版本。 这种机制很复杂,并且没有完整记录,但是glibc手册的“维护”附录 ,特别是其“源布局”和“移植”部分,对它进行了详尽的介绍。


libm_alias_float (__sqrt, sqrt)安排__sqrtf也使用名称sqrtf ,但作为弱别名 为了符合标准,这是必需的。 如果您需要更多详细信息,请问一个单独的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM