在Linux内核上,在包含kernel_fpu_begin()的文件上生成和优化FP / SIMD代码?

问题描述 投票:0回答:1

我知道禁止在内核中使用任何种类的浮点代码,并且我们绝不应该使用任何可以生成FP / SIMD指令的GCC标志,但是使用某些源代码(尤其是arch/x86/crypto/*)呢? kernel_fpu_begin()kernel_fpu_end()

[Example 1example 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()的文件中,我像这样通过FPU_CFLAGS传递Makefiles

CFLAGS_sha512_ssse3_glue.o := $(FPU_CFLAGS)

这是正确的,它将优化FP / SIMD代码吗?还是不需要,并且此实现甚至可能破坏FPU / SIMD的状态?

linux-kernel cryptography compiler-optimization simd fpu
1个回答
2
投票

这是正确的

不,绝对不要这样做。这些选项告诉GCC它可以在此编译单元中使用SIMD / FP指令anywhere,包括before 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()的内核代码也使用嵌入式asm运行SIMD指令。这将发出SIMD指令编译器的任何帮助。

或者从理论上讲,某些内核代码可以使用函数属性,例如__attribute__((target("sse2")))或类似的属性,用于从kernel_fpu_begin() / end块内部调用的辅助函数。但是我认为Linux更喜欢内联汇编,而不是内在汇编或自动向量化。

如果内核从中获得零收益,它就不会费心地包含kernel_fpu_begin() / end调用。顺便说一句,您可以反汇编相关的.ko内核模块,并查看它们实际上是否包含使用XMM寄存器的SIMD指令。使用objdump -drwC -Mintel foo.ko

© www.soinside.com 2019 - 2024. All rights reserved.