为啥内核中不使用 SIMD 指令?
Posted
技术标签:
【中文标题】为啥内核中不使用 SIMD 指令?【英文标题】:Why are SIMD instructions not used in kernel?为什么内核中不使用 SIMD 指令? 【发布时间】:2017-10-10 23:54:44 【问题描述】:我在内核中找不到太多使用 SIMD 指令(如 SSE/AVX)的地方(除了一个用于加速 RAID6 奇偶校验计算的地方)。
Q1) 有什么具体原因,还是只是缺少用例?
Q2) 如果我想使用 SIMD 指令,比如设备驱动程序,今天需要做什么?
Q3) 将像 ISPC 这样的框架合并到内核中会有多难(仅用于实验)?
【问题讨论】:
【参考方案1】:保存/恢复 FPU(包括 SIMD 向量寄存器)状态比仅整数 GP 寄存器状态更昂贵。在大多数情况下,这根本不值得。
在 Linux 内核代码中,您只需在代码周围调用 kernel_fpu_begin()
/ kernel_fpu_end()
。这就是 RAID 驱动程序的作用。参见http://yarchive.net/comp/linux/kernel_fp.html。
x86 没有任何面向未来的方法来保存/恢复一个或几个向量寄存器。 (除了使用旧版 SSE 指令手动保存/恢复 xmm
寄存器外,如果用户空间的任何 ymm/zmm 寄存器的上半部分脏,则可能导致 SSE/AVX transition stalls on Intel CPUs。
旧版 SSE 起作用的原因是,当英特尔想要引入 AVX 时,一些 Windows 驱动程序已经这样做了,因此他们发明了这种转换惩罚的东西,而不是让旧版 SSE 指令将 ymm 寄存器的高 128b 归零。 (有关该设计决策的更多详细信息,请参阅this。)因此,基本上我们可以将 SSE/AVX 转换惩罚混乱归咎于 Windows 仅二进制驱动程序。
关于非 x86 架构的 IDK,以及现有 SIMD 指令集是否有面向未来的方法来保存/恢复将继续适用于更长向量的寄存器。如果扩展继续使用多个 32 位 FP 寄存器作为单个更宽寄存器的模式,ARM32 可能会。 (例如,q2
由 s8
到 s11
组成。)因此,如果 256b NEON 扩展只允许您将 2 个 q
寄存器用作一个 256b,那么保存/恢复一对 q
寄存器应该是面向未来的登记。或者,如果新的更宽向量是独立的,并且不扩展现有寄存器。
【讨论】:
相关:memcpy moving 128 bit in linux。我的回答还提到kernel_fpu_end()
实际上在 Linux 3.7 及更高版本中“急切”地恢复了 FPU 状态,因此不要围绕小块工作使用多个开始/结束调用。以上是关于为啥内核中不使用 SIMD 指令?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 AngularJS 指令中不推荐使用 `replace` 属性? [复制]
DSP视频教程DSP视频教程第10期:DSP运算加速的精髓,含SIMD指令,饱和运算指令和浮点以及定点的MAC乘累加指令