只有一个可执行文件即可进行跨平台 SIMD 调用?

Cross-platform SIMD calls possible with only one executable?

本文关键字:跨平台 SIMD 调用 有一个 可执行文件      更新时间:2023-10-16

我最近对 SIMD 优化产生了兴趣,因为我想在一段时间没有编程后再次在 C++ 中编程。请描述一下,因为我仍然是 SIMD 说明的初学者。

我的问题是:是否可以在C++中编译一个支持各种 SIMD 指令集并实时选择最佳指令集的跨平台可执行文件?在性能方面最好,通常最新的指令集更好。

示例:我在Windows 10上用i7-7700K编译一个游戏,并将其放在Steam上。不同的用户很可能具有支持不同 SIMD 指令集的不同 CPU。启动游戏时,会检测并使用最佳 SIMD 指令集。

当然,我必须调整我的代码并支持一些手工选择的 SIMD 指令集。

通常,问题是您希望使用 SIMD 的粒度级别...像 D3DXMath 这样的旧数学库使用间接跳转(即虚拟方法(在运行时选择针对该指令集优化的函数版本。虽然这在理论上有效,但该函数必须做足够的工作来覆盖间接调用的开销。

例如:如果您调用D3DXVec3Dot并且它为 SSE/SSE2、SSE3 或 SSE4.1 选择了不同的版本,则首先调用函数的成本很可能比性能节省的成本更高。要真正从这种优化中受益,您需要拥有更大规模的例程,一次执行数千次计算,而不是微函数。

请注意,这就是为什么 DirectXMath 是一个完全不使用间接跳转/调度的全内联库。你可以指望 SSE/SSE2 始终支持 x64,并且 x86 基本上始终支持它。如果您碰巧正在为始终具有AVX(例如Xbox One(的平台构建EXE/DLL,请使用/arch:AVX,DirectXMath库将在有意义的地方使用AVX,SSE4.1,SSE3,SSE2/SSE。请参阅此博客文章系列。