我有一个使用 CPU 特定功能的 Python 扩展,
如果可供使用的话。这是通过运行时检查来完成的。如果
硬件支持POPCNT
指令,然后选择一个
我的内部循环的实现,如果 SSSE3 可用的话
它选择另一个,否则它会回退到通用版本
我的性能关键内核。 (大约 95% 以上的时间是
花费在这个内核中。)
不幸的是,有一种我没有预料到的故障模式。我
使用-mssse3
and -O3
编译所有的 C 代码,即使
只有一个文件需要它-mssse3
选项。因此,编译其他文件时预期 SSSE3 将存在。这会导致该行出现段错误:
start_target_popcount = (int)(query_popcount * threshold);
因为编译器使用了fisttpl
,这是一条 SSSE3 指令。
毕竟,我告诉它假设 SSSE3 存在。
我的软件包的 Debian 打包器最近遇到了这个问题,
因为测试机有一个GCC可以理解-mssse3
和
生成代码时考虑到了这一点,但机器本身有一个
没有这些指令的旧CPU。
我想要一个解决方案,使相同的二进制文件可以在旧机器上运行
在较新的发行版上,Debian 维护者可以将其用于该发行版。
理想情况下,我想说只编译一个文件
与-mssse3
选项。由于我的 CPU 特定选择器代码
不是此文件的一部分,不会执行任何 SSSE3 代码
除非CPU支持。
但是,我想不出任何方法来告诉distutils
那
一组编译器选项特定于单个文件。
这可能吗?
一个非常丑陋的解决方案是创建两个(或更多)Extension
)类,一个用于保存 SSSE3 代码,另一个用于其他所有内容。然后你可以在 python 层整理界面。
c_src = [f for f in my_files if f != 'ssse3_file.c']
c_gen = Extension('c_general', sources=c_src,
libraries=[], extra_compile_args=['-O3'])
c_ssse3 = Extension('c_ssse_three', sources=['ssse3_file.c'],
libraries=[], extra_compile_args=['-O3', '-mssse3'])
并在一个__init__.py
某处
from c_general import *
from c_ssse_three import *
当然,您不需要我写出该代码!我知道这并不枯燥,我期待阅读更好的答案!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)