【发布时间】:2012-01-14 06:59:19
【问题描述】:
我想将运行时 CPU 调度集成到我的库中。我有一些功能的几个版本,针对 sse2/sse3/avx 和 x87 通用变体进行了优化。我想将所有版本编译成单个 .so 库,我想如何实现一个 cpu 调度程序。
我认为最快的方法是在链接步骤(动态链接)进行 cpu 调度,所以当 ld.so 加载我的库时,我希望它检查 cpu 是否支持 sse2、sse3 或 avx,然后我希望 ld.so 选择正确的功能集。
例如(使用gcc target attribute):
图书馆:
float* func3_generic(float *a, float *b) __attribute__ ((__target__ ("fpmath=387")));
float* func3_sse2(float *a, float *b) __attribute__ ((__target__ ("sse2")));
float* func3_sse3(float *a, float *b) __attribute__ ((__target__ ("sse3")));
float* func3_avx(float *a, float *b) __attribute__ ((__target__ ("avx")));
我想要一些特殊符号func3(),它将由链接器(ld.so)设置为最高级的func3_generic、func3_sse2、func3_sse3、func3_avx。所以,如果cpu是Core i7-xxxx,我希望每次调用func3都是调用func3_avx,如果cpu是PentiumPro,调用func3就是调用func3_generic。
同时我不想手动编写大量调度代码,我希望以最小的开销选择正确的变体(没有额外的间接跳转)。这意味着我可以在应用程序启动时提供额外的时间,但在调用此函数时没有任何额外的时间(在某些情况下调用次数非常多)。
更新。 Linker可以根据AUXV向量进行调度,AT_HWCAP:字段:
$ LD_SHOW_AUXV=1 /bin/echo
...
AT_HWCAP: fpu ... mmx fxsr sse sse2
【问题讨论】:
-
IBM 的 Power Platform 好文章,ibm.com/developerworks/wikis/display/LinuxP/Optimized+Libraries 和 gnu_indirect_function(或 STT_GNU_IFUNC)看起来很有前途
-
是的,这就是 STT_IFUNC 的用途(顺便说一句,这似乎是更改 Linux 的 ELF 可执行文件的 ABI 字段所需的第一个扩展)。
-
ninjalj,您能否添加 STT_IFUNC 作为答案,并简单说明它的工作原理以及为什么需要更改 ABI Fieldo?
标签: c linux optimization linker