osg*_*sgx 5 c linux optimization linker
我想将运行时CPU Dispatch集成到我的库中.我有几个版本的功能,针对sse2/sse3/avx和x87通用变体进行了优化.我想将所有版本编译成单个.so库,我想如何实现一个cpu调度程序.
我认为最快的方法是在链接步骤(动态链接)获取cpu调度,所以当ld.so将加载我的库时,我希望它检查,cpu是否支持sse2,sse3或avx,然后我想要ld .so选择正确的功能集.
例如(使用gcc目标属性):
图书馆:
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")));
Run Code Online (Sandbox Code Playgroud)
我想有一些特殊的符号func3(),这将通过连接器(ld.so)被设置好的,以最先进的func3_generic,func3_sse2,func3_sse3,func3_avx.所以,如果cpu是Core i7-xxxx,我希望每次调用func3都会调用func3_avx,如果cpu是PentiumPro,调用func3将调用func3_generic.
同时我不想手动编写大量的调度代码,我希望以最小的开销选择正确的变量(没有额外的间接跳转).这意味着我可以在应用程序启动时花费额外的时间,但在调用此函数时没有任何额外的时间(在某些情况下会有非常多的调用).
UPDATE.链接器可以根据AUXV向量,AT_HWCAP:字段进行调度:
$ LD_SHOW_AUXV=1 /bin/echo
...
AT_HWCAP: fpu ... mmx fxsr sse sse2
Run Code Online (Sandbox Code Playgroud)
Jam*_*mes -1
如何使用函数指针数组,然后使用 CPUID 指令让它们在启动时指向特定的实现。启动时所需的周期数应该很小。
如果您确实想避免任何启动成本,另一种方法是编写另一个小程序来查询 CPU 的功能,然后为 gcc 构造一个命令行,并定义一些宏,以便仅编译某些函数实现。