在包含 kernel_fpu_begin() 的文件上生成和优化 Linux 内核中的 FP/SIMD 代码?
Posted
技术标签:
【中文标题】在包含 kernel_fpu_begin() 的文件上生成和优化 Linux 内核中的 FP/SIMD 代码?【英文标题】:Generate and optimize FP / SIMD code in the Linux Kernel on files which contains kernel_fpu_begin()? 【发布时间】:2020-04-30 16:44:46 【问题描述】:我知道在内核中禁止使用任何类型的浮点代码,我们绝不应该使用任何可能生成 FP / SIMD 指令的 GCC 标志,但是一些源代码(尤其是arch/x86/crypto/*
)呢?使用kernel_fpu_begin()
和kernel_fpu_end()
?
Example 1, example 2.
我有一个古老的 Intel Core 2 Duo CPU,用于我的 64 位 Linux 内核,在主要的 Makefile
中,我使用以下 C 标志:
# Target specific Flags
KBUILD_CFLAGS += \
-m64 \
-march=core2 \
-mtune=core2 \
-mfpmath=sse \
-msoft-float \
-mno-fp-ret-in-387 \
-mno-mmx \
-mno-sse \
-mno-sse2 \
-mno-sse3 \
-mno-ssse3
# FPU Flags
FPU_CFLAGS := $(KBUILD_CFLAGS) \
-mhard-float \
-mfp-ret-in-387 \
-mmmx \
-msse \
-msse2 \
-msse3 \
-mssse3 \
-ftree-vectorize
在存在kernel_fpu_begin()
的文件中,我在他们的Makefiles
中传递FPU_CFLAGS
,如下所示:
CFLAGS_sha512_ssse3_glue.o := $(FPU_CFLAGS)
这是正确的吗?它会优化 FP / SIMD 代码吗?还是不需要它,这个实现甚至可能破坏 FPU / SIMD 的状态?
【问题讨论】:
【参考方案1】:这样说对吗
不,绝对不要这样做。这些选项告诉 GCC 它可以在此编译单元中任何地方使用 SIMD/FP 指令,包括 之前 kernel_fpu_begin()
或kernel_fpu_end()
之后,或在从不调用kernel_fpu_begin()
的函数中。
例如它可以发出 movdqu
加载或存储以复制结构的 16 个字节,然后 corrupt user-space XMM register state 之前 kernel_fpu_begin
保存它。
是否会优化 FP/SIMD 代码?
不,使用kernel_fpu_begin()
的内核代码也使用内联汇编来运行 SIMD 指令。这将发出 SIMD 指令编译器没有任何帮助。
或者在理论上,某些内核代码可以使用像 __attribute__((target("sse2")))
这样的函数属性或类似的东西,用于从 kernel_fpu_begin()
/ end
块内部调用的辅助函数。但我认为 Linux 更喜欢内联汇编而不是内联汇编或自动矢量化。
内核不会费心包含kernel_fpu_begin()
/end
调用,如果它从中获得零收益。顺便说一句,您可以反汇编相关的.ko
内核模块,并查看它们实际上包含使用 XMM 寄存器的 SIMD 指令。使用objdump -drwC -Mintel foo.ko
【讨论】:
以上是关于在包含 kernel_fpu_begin() 的文件上生成和优化 Linux 内核中的 FP/SIMD 代码?的主要内容,如果未能解决你的问题,请参考以下文章
linux 查看文件夹下的文件个数(当前目录的文件数)//包含子目录