栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何在Linux上基于CPU功能进行运行时绑定

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何在Linux上基于CPU功能进行运行时绑定

编辑:
我后来发现,下面描述的技术仅在有限的情况下有效。具体来说,您的共享库必须仅包含函数,而没有任何全局变量。如果要分派到的库中有全局变量,则最终将出现运行时动态链接器错误。这是因为全局变量在调用共享库构造函数之前已重定位。因此,链接器需要尽早解析这些引用,然后才能运行这里描述的调度方案。


完成所需操作的一种方法是(ab)使用

DT_SONAME
共享库的ELF标头中的字段。这可用于更改动态加载程序(
ld-linux-so*
)在运行时加载的文件的名称,以解决共享库的依赖性。最好用一个例子来解释。说我
libtest.so
用以下命令行编译共享库:

g++ test.cc -shared -o libtest.so -Wl,-soname,libtest_dispatch.so

这将创建一个共享库,其名称为

libtest.so
,但其
DT_SONAME
字段设置为
libtest_dispatch.so
。让我们看看将程序链接到该程序时会发生什么:

g++ testprog.cc -o test -ltest

让我们检查生成的应用程序二进制文件的运行时库依赖项

test

> ldd testlinux-vdso.so.1 =>  (0x00007fffcc5fe000)libtest_dispatch.so => not foundlibc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd1e4a55000)/lib64/ld-linux-x86-64.so.2 (0x00007fd1e4e4f000)

请注意,

libtest.so
动态加载程序不是要查找而是要加载
libtest_dispatch.so
。您可以利用它来实现所需的调度功能。这是我的处理方式:

  • 创建共享库的各种版本。我假设有一些“通用”版本可以始终使用,并在运行时适当地使用其他优化版本。我会说出通用版“普通的”库名

    libtest.so
    ,并命名无论您选择的其他人(例如
    libtest_sse2.so
    libtest_avx.so
    等)。

  • 链接库的通用版本时,请将其覆盖

    DT_SONAME
    到其他名称,例如
    libtest_dispatch.so

  • 创建一个名为的调度程序库

    libtest_dispatch.so
    。在应用程序启动时加载调度程序时,它负责加载库的适当实现。以下是伪代码,其实现
    libtest_dispatch.so
    可能如下所示:

    #include <dlfcn.h>

    include

    // the attribute ensures that this function is called when the library is loaded
    attribute((constructor)) void init()
    {
    // manually load the appropriate shared library based upon what the CPU supports
    // at runtime
    if (avx_is_available) dlopen(“libtest_avx.so”, RTLD_NOW | RTLD_GLOBAL);
    else if (sse2_is_available) dlopen(“libtest_sse2.so”, RTLD_NOW | RTLD_GLOBAL);
    else dlopen(“libtest.so”, RTLD_NOW | RTLD_GLOBAL);
    // NOTE: this is just an example; you should check the return values from
    // dlopen() above and handle errors accordingly
    }

  • 将应用程序与您的库链接时,请将其与“ vanilla”链接

    libtest.so
    ,该文件已
    DT_SONAME
    被覆盖以指向调度程序库。这使得分派对于使用您的库的所有应用程序作者基本上都是透明的。

这应该如上所述在Linux上工作。在Mac OS上,共享库的“安装名称”类似于

DT_SONAME
ELF共享库中使用的“安装名称”
,因此可以改用与上述过程非常相似的过程。我不确定Windows是否可以使用类似的东西。

注意:上面
有一个重要的假设:库的各种实现之间的ABI兼容性。也就是说,您的库的设计应使其在链接时可以安全地链接到最通用的版本,而

libtest_avx.so
在运行时使用优化的版本(例如)。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/397563.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号