关于 C 中 SIMD 的说明
Clarifications about SIMD in C
这就是我对 SIMD 的了解。单指令多数据是一种处理数据的方法,它对多值向量执行相同的指令。 SIMD根据机器的处理器(SSE、SSE2、NEON...)在不同的级别实现,每个级别提供不同的指令集。
我们可以通过包含 immintrin.h
来使用这些指令集。我还没有真正理解的是:在实际使用 SIMD 开发某些东西时,我们是否应该关心检查支持哪些指令集?开发此类程序时的最佳做法是什么?例如,如果不支持指令集,我们该怎么办?我们应该提供非 SIMD 替代方案还是编译器为我们取消向量化整个过程?
当然我们需要注意支持哪个ISA,因为如果我们使用未知指令那么程序将被不支持的指令信号杀死。此外,它允许我们针对每个架构进行优化,例如在 CPUs 上使用 AVX-512 我们可以使用 AVX-512 以获得更好的性能,但如果在较旧的 CPU 上我们可以回退到适当的该架构的版本
What are the best practices when developing such programs?
没有通用的最佳做法。这取决于每种情况,因为每个编译器都有不同的工具
- 如果您的编译器不支持动态调度,那么您需要为每个 ISA 编写单独的代码,并为当前平台调用相应的版本
- 一些编译器会自动分配到针对 运行 平台优化的版本,例如 ICC 可以编译一个热循环来分离 SSE/AVX/AVX-512 的版本并跳转到正确的版本以获得最佳性能。
- 其他一些编译器支持编译为单个函数的不同版本并自动调度,但您需要指定要优化的函数。例如,在 GCC、Clang 和 ICC 中,您可以使用属性
target
和 target_clones
。参见
should we care about checking which instruction sets are supported?
通常是,但并非总是如此。如果你为PC编译64位代码,保证有SSE1和SSE2,这两个是AMD64指令集的一部分,保证支持。
What are the best practices when developing such programs?
与人们协商您正在使用的软件的最低硬件要求。如果您没有老板、客户或用户,请查找一些统计数据并尝试做出有根据的猜测。 Steam 有一个很好的 stats for PC gamers 安装了他们的软件,展开“其他设置”,您会看到具有特定指令集的全球用户百分比。
就我个人而言,我认为现在到 2021 年通常可以要求 SSE 达到并包括 SSE 4.1,如果不支持则启动失败。假设您优雅地做到了这一点,即将其写入硬件要求,并在运行时向最终用户显示一条关于不受支持的可理解的错误消息 CPU.
should we provide a non-SIMD alternative
过去十年售出的新电脑中有 99% 至少有 4GB 内存和 64 位 OS。我认为对于大多数项目来说,只发布 64 位二进制文件是可以的,这给了你 SSE 1 和 2,不需要标量替代品。
有时,当我需要仅支持 SSE CPUs 但 AVX 在性能方面带来太多利润时,我确实实施了几个替代方案和运行时调度。
这就是我对 SIMD 的了解。单指令多数据是一种处理数据的方法,它对多值向量执行相同的指令。 SIMD根据机器的处理器(SSE、SSE2、NEON...)在不同的级别实现,每个级别提供不同的指令集。
我们可以通过包含 immintrin.h
来使用这些指令集。我还没有真正理解的是:在实际使用 SIMD 开发某些东西时,我们是否应该关心检查支持哪些指令集?开发此类程序时的最佳做法是什么?例如,如果不支持指令集,我们该怎么办?我们应该提供非 SIMD 替代方案还是编译器为我们取消向量化整个过程?
当然我们需要注意支持哪个ISA,因为如果我们使用未知指令那么程序将被不支持的指令信号杀死。此外,它允许我们针对每个架构进行优化,例如在 CPUs 上使用 AVX-512 我们可以使用 AVX-512 以获得更好的性能,但如果在较旧的 CPU 上我们可以回退到适当的该架构的版本
What are the best practices when developing such programs?
没有通用的最佳做法。这取决于每种情况,因为每个编译器都有不同的工具
- 如果您的编译器不支持动态调度,那么您需要为每个 ISA 编写单独的代码,并为当前平台调用相应的版本
- 一些编译器会自动分配到针对 运行 平台优化的版本,例如 ICC 可以编译一个热循环来分离 SSE/AVX/AVX-512 的版本并跳转到正确的版本以获得最佳性能。
- 其他一些编译器支持编译为单个函数的不同版本并自动调度,但您需要指定要优化的函数。例如,在 GCC、Clang 和 ICC 中,您可以使用属性
target
和target_clones
。参见
should we care about checking which instruction sets are supported?
通常是,但并非总是如此。如果你为PC编译64位代码,保证有SSE1和SSE2,这两个是AMD64指令集的一部分,保证支持。
What are the best practices when developing such programs?
与人们协商您正在使用的软件的最低硬件要求。如果您没有老板、客户或用户,请查找一些统计数据并尝试做出有根据的猜测。 Steam 有一个很好的 stats for PC gamers 安装了他们的软件,展开“其他设置”,您会看到具有特定指令集的全球用户百分比。
就我个人而言,我认为现在到 2021 年通常可以要求 SSE 达到并包括 SSE 4.1,如果不支持则启动失败。假设您优雅地做到了这一点,即将其写入硬件要求,并在运行时向最终用户显示一条关于不受支持的可理解的错误消息 CPU.
should we provide a non-SIMD alternative
过去十年售出的新电脑中有 99% 至少有 4GB 内存和 64 位 OS。我认为对于大多数项目来说,只发布 64 位二进制文件是可以的,这给了你 SSE 1 和 2,不需要标量替代品。
有时,当我需要仅支持 SSE CPUs 但 AVX 在性能方面带来太多利润时,我确实实施了几个替代方案和运行时调度。