如何为一个 Python/C 扩展源文件指定不同的编译器标志?

2024-04-15

我有一个使用 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(使用前将#替换为@)

如何为一个 Python/C 扩展源文件指定不同的编译器标志? 的相关文章

随机推荐