在包含 kernel_fpu_begin() 的文件的 Linux 内核中生成和优化 FP/SIMD 代码?
Generate and optimize FP / SIMD code in the Linux Kernel on files which contains kernel_fpu_begin()?
我知道在内核中禁止使用任何类型的浮点代码,我们永远不应该使用任何可以生成 FP / SIMD 指令的 GCC 标志,但是一些源代码呢(尤其是 arch/x86/crypto/*
) 使用 kernel_fpu_begin()
和 kernel_fpu_end()
?
我有一个古老的 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()
的文件中,我将 FPU_CFLAGS
传递到它们的 Makefiles
中,如下所示:
CFLAGS_sha512_ssse3_glue.o := $(FPU_CFLAGS)
这是否正确,是否会优化 FP/SIMD 代码?还是不需要并且此实现甚至可以破坏 FPU / SIMD 的状态?
Is this correct
不,绝对不要这样做。这些选项告诉GCC它可以在这个编译中使用SIMD/FP指令anywhere单位,包括 before kernel_fpu_begin()
或 kernel_fpu_end()
之后,或在从不调用 kernel_fpu_begin()
.
的函数中
例如它可以发出 movdqu
加载或存储以复制结构的 16 个字节并 corrupt user-space XMM register state before kernel_fpu_begin
保存它。
and will optimize the FP / SIMD Code?
不,使用 kernel_fpu_begin()
的内核代码也使用内联 asm 到 运行 SIMD 指令。这将发出 SIMD 指令 而无需 编译器的任何帮助。
或者理论上一些内核代码可以使用函数属性,如 __attribute__((target("sse2")))
或类似的东西,用于从 kernel_fpu_begin()
/ end
块内部调用的辅助函数。但我认为 Linux 更喜欢内联 asm 而不是加内在函数或自动矢量化。
如果内核从中获得的收益为零,则它不会费心去包含 kernel_fpu_begin()
/end
调用。顺便说一句,您可以反汇编相关的 .ko
内核模块并查看它们实际上包含使用 XMM 寄存器的 SIMD 指令。使用 objdump -drwC -Mintel foo.ko
我知道在内核中禁止使用任何类型的浮点代码,我们永远不应该使用任何可以生成 FP / SIMD 指令的 GCC 标志,但是一些源代码呢(尤其是 arch/x86/crypto/*
) 使用 kernel_fpu_begin()
和 kernel_fpu_end()
?
我有一个古老的 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()
的文件中,我将 FPU_CFLAGS
传递到它们的 Makefiles
中,如下所示:
CFLAGS_sha512_ssse3_glue.o := $(FPU_CFLAGS)
这是否正确,是否会优化 FP/SIMD 代码?还是不需要并且此实现甚至可以破坏 FPU / SIMD 的状态?
Is this correct
不,绝对不要这样做。这些选项告诉GCC它可以在这个编译中使用SIMD/FP指令anywhere单位,包括 before kernel_fpu_begin()
或 kernel_fpu_end()
之后,或在从不调用 kernel_fpu_begin()
.
例如它可以发出 movdqu
加载或存储以复制结构的 16 个字节并 corrupt user-space XMM register state before kernel_fpu_begin
保存它。
and will optimize the FP / SIMD Code?
不,使用 kernel_fpu_begin()
的内核代码也使用内联 asm 到 运行 SIMD 指令。这将发出 SIMD 指令 而无需 编译器的任何帮助。
或者理论上一些内核代码可以使用函数属性,如 __attribute__((target("sse2")))
或类似的东西,用于从 kernel_fpu_begin()
/ end
块内部调用的辅助函数。但我认为 Linux 更喜欢内联 asm 而不是加内在函数或自动矢量化。
如果内核从中获得的收益为零,则它不会费心去包含 kernel_fpu_begin()
/end
调用。顺便说一句,您可以反汇编相关的 .ko
内核模块并查看它们实际上包含使用 XMM 寄存器的 SIMD 指令。使用 objdump -drwC -Mintel foo.ko