在eglibc-2.13中,sin()函数是如何实现的?

3
我需要追踪eglibc-2.13中double sin(double x)函数的具体实现方式。我下载了源代码,唯一有意义的部分是与平台相关的__sin函数。它是否是/usr/lib/i386-linux-gnu/libm.a中包含的内容的核心?
如何跟踪从sin()到__sin()的宏定义?我真正需要的是确切的代码(包括文件名和行号),以及构建过程推断使用哪个实现的方法。该架构为i386。
2个回答

5
(e)glibc的编译过程十分复杂,非常玄学。你不需要试图去理解它。但是,glibc遵循一种公共函数一个文件的编码风格,因此,如果你拥有源代码树并且想要找到某个函数的实现,最简单的方法是:
$ find * -name '*function*' -print

从最高层级开始,将function替换为函数名称。

具体讨论sin:数学函数的通用实现在math目录中:然而,似乎没有sin的通用定义。所以下一个地方要查找的是sysdeps。所有非通用的内容都在sysdeps中,特别是sysdeps/ieee754是所有数学函数都依赖于IEEE 754浮点规范但没有其他系统依赖项的地方。此目录按类型组织:sysdeps/ieee754/dbl-64包含所有IEEE double的数学函数。这里你会找到sysdeps/ieee754/dbl-64/s_sin.c,这就是你要找的代码。(这些文件上的e_s_k_等前缀曾经有意义,但我认为现在已经没有了。)

如果有一个特定处理器的汇编语言实现的sin,它将在sysdeps的其他位置的名为sin.S(或可能是s_sin.S)的文件中。不过似乎没有这样的文件。


1
据我所知,sin 没有汇编代码,因为除了优化 C 代码已经执行的操作之外,没有直接的方法来编写它。x87 fsin/fcos 指令不足以实现符合 IEEE 标准的 sin 函数。如果您想要一个非符合性的速度优化,gcc 的 -ffast-math 可以为您完成这项工作。 - R.. GitHub STOP HELPING ICE
有可能有人会编写手动优化的汇编实现,利用SSE或其他技术,但至少在x86上似乎没有人费心过。 - zwol
@R..:在汇编中直接写sin而不参考C代码是没有障碍的。 - Eric Postpischil
@EricPostpischil: 我并没有说有这样的东西。我只是说,汇编实现只是执行与当前 C 代码相同的算法,但是是手动优化而不是由编译器进行优化。我所谓的“直接”,是指像 fsqrt 指令那样能够完成整个 sqrt() 的工作,或者以更不平凡的例子来说,你可以使用专门的指数函数指令在 387 汇编中实现 exp - R.. GitHub STOP HELPING ICE
@R..:在编写 sincos 实现时,有许多事情可能不容易用 C 语言表示。就我个人而言,在 64 位平台上,可以使用整数指令进行参数缩减,并利用 x86 64bx64b -> 128b 乘法指令;也可以进行浮点运算以进行缩减,并利用 SSE4.1 的 roundsd 指令以静态舍入模式进行最终舍入到整数。我相信我还可以想到更多的例子。 - Stephen Canon
你有没有想到一种使用整数运算来有效地进行参数约减的方法?三角函数参数约减非常难以正确处理,我总是对新的方法感兴趣。 - R.. GitHub STOP HELPING ICE

1

不是答案,只是一些背景知识:

当您在C代码中使用sin()cos()时,几乎肯定是编译器提供实现,而不是您的C库。例如,请查看GCC提供的内置列表。链接页面还描述了使用内置函数而不是C库提供版本的情况。


但是怎么做呢?我正在使用libc6-dev中的libm.a进行链接: > locate libm.a /usr/lib/i386-linux-gnu/libm.a> apt-file search /usr/lib/i386-linux-gnu/libm.a libc6-dev: /usr/lib/i386-linux-gnu/libm.a - d33tah
几乎所有这些GCC内置函数只是进行一些优化,然后转发到C库例程或类似的例程。例如,如果GCC知道C库有sinf可用,它可能会将float y = sin(x)(其中x也是float)转换为对sinf的调用。已经讨论过向GCC添加完整的C99数学库,但据我所知尚未实现。 - zwol
@Zack,你是对的。我没有注意到这个链接性,因为我大多数时候使用的是针对SSE2/3的向量扩展内置函数,它们不调用任何函数,而是直接生成实际操作。我真的没有想到GCC不会将这些内置函数映射到汇编指令中...好吧,我猜这是在x86-64上优化紧密计算仿真代码的另一个地方。感谢提醒! - Nominal Animal
我不知道有SSE三角函数指令,我以为那些已经随着老式的x87 FPU指令集一起过时了。无论如何,即使是对于-ffast-math来说,我也认为它们太不准确了。 - zwol
不,只有加法、减法、乘法、除法、平方根、不精确的倒数平方根、最小值、最大值、比较、二进制操作、移动和混洗/交换。在任何性能关键的东西中,我很久没有需要 sin()cos() 了;我非常惊讶它们是外部函数而不是内联的。 - Nominal Animal

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