移植glibc 2.25并测试内存功能

Port glibc 2.25 and test memory functions

我正在研究 glibc-2.25 中具有各种版本(sse4、ssse3、avx2、avx512)的一些内存函数(memcpy、memset、memmove)是否可以提高我们在 Linux 中的服务器程序的性能(glibc 2.12).
我的第一次尝试是按照这里的说明 https://sourceware.org/glibc/wiki/Testing/Builds 下载 glibc-2.25 和 build/test 的 tar 球。我手动注释掉内核版本检查,一切顺利。然后将一个测试程序与新构建的 glibc 链接,其过程在 glibc wiki 的 "Compile against glibc build tree" 部分列出,'ldd test' 表明它确实依赖于预期的库:

    # $GLIBC is /data8/home/wentingli/temp/glibc/build
    libm.so.6 => /data8/home/wentingli/temp/glibc/build/math/libm.so.6 (0x00007fe42f364000)
    libc.so.6 => /data8/home/wentingli/temp/glibc/build/libc.so.6 (0x00007fe42efc4000)
    /data8/home/wentingli/temp/glibc/build/elf/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007fe42f787000)
    libdl.so.2 => /data8/home/wentingli/temp/glibc/build/dlfcn/libdl.so.2 (0x00007fe42edc0000)
    libpthread.so.0 => /data8/home/wentingli/temp/glibc/build/nptl/libpthread.so.0 (0x00007fe42eba2000)

我使用 gdb 来验证实际调用了哪个 memset/memcpy,但它总是显示使用了 __memset_sse2_unaligned_erms,而我期待该函数的某些更高级版本(avx2、avx512)可能是in use。 我的问题是:

  1. glibc-2.25 select最合适的内存版本是否自动根据cpu/os/memory地址运行?如果不是,是我在 glibc 构建期间缺少任何配置还是我的设置有问题?
  2. 是否有任何其他方法可以从较新的 glibc 移植内存函数?

如有任何帮助或建议,我们将不胜感激。

在 x86 上,glibc 会自动 select 一个最适合 CPU 系统的实现,通常基于 Intel 的指导。 (这是否是您场景的最佳选择可能并不明确,因为许多矢量指令的性能权衡非常复杂。)只有在工具链中明确禁用 IFUNC 时,才不会发生这种情况,但 __memset_sse2_unaligned_erms 不是默认实现,因此这不适用于此处。 ERMS 功能是最近推出的,所以这并非完全不合理。

构建一个新的 glibc 可能是测试这些字符串函数的正确方法。理论上,您也可以使用 LD_PRELOAD 来覆盖 glibc 提供的函数,但是在 glibc 构建系统之外构建字符串函数有点麻烦。

如果你想 运行 一个针对打过补丁的 glibc 的程序而不安装后者,你需要使用 glibc 构建目录中的 testrun.sh 脚本(或类似的方法)。