我希望将运行时CPU分派集成到我的库中。我有一些函数的几个版本,针对sse2/sse3/avx进行了优化,并有一个x87通用变体。我想将所有版本编译成单个.so库,并考虑如何实现CPU分派。
我认为最快的方式是在链接步骤(动态链接)中获取CPU分派,因此当ld.so加载我的库时,我希望它检查CPU是否支持sse2、sse3或avx,然后我希望ld.so选择正确的函数集。
例如(使用gcc目标属性):
库:
我希望有一个特殊的符号
同时,我不想手动编写大量的分派代码,并且希望以最小的开销选择正确的变体(没有额外的间接跳转)。这意味着我可以在应用程序启动时承受额外的时间,但在调用此函数时不需要任何额外的东西(在某些情况下调用次数非常高)。
更新。链接器可以根据AUXV向量的
我认为最快的方式是在链接步骤(动态链接)中获取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")));
我希望有一个特殊的符号
func3()
,由链接器(ld.so)设置为func3_generic
、func3_sse2
、func3_sse3
和func3_avx
中最先进的一个。因此,如果CPU是Core i7-xxxx,我希望每次对func3的调用都是对func3_avx的调用,如果CPU是PentiumPro,则对func3的调用将是对func3_generic的调用。同时,我不想手动编写大量的分派代码,并且希望以最小的开销选择正确的变体(没有额外的间接跳转)。这意味着我可以在应用程序启动时承受额外的时间,但在调用此函数时不需要任何额外的东西(在某些情况下调用次数非常高)。
更新。链接器可以根据AUXV向量的
AT_HWCAP:
字段进行分派:$ LD_SHOW_AUXV=1 /bin/echo
...
AT_HWCAP: fpu ... mmx fxsr sse sse2