跨平台 SIMD 调用可能只用一个可执行文件吗?

Cross-platform SIMD calls possible with only one executable?

我最近对 ​​SIMD 优化产生了兴趣,因为我想在一段时间不这样做后再次用 C++ 编程。请描述一下,因为我仍然是 SIMD 指令的初学者。

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

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

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

一般来说,问题是您想要使用 SIMD 的粒度级别...D3DXMath 等较旧的数学库在运行时使用间接跳转(即虚拟方法)到 select 优化的函数版本对于那个指令集。虽然这在理论上可行,但该函数必须做足够的工作来弥补间接调用的开销。

例如:如果您调用 D3DXVec3Dot,它 select 是 SSE/SSE2、SSE3 或 SSE4.1 的不同版本,很可能是第一个调用函数的成本地方是更昂贵的性能节省。要真正从这种优化中获益,您需要有更大规模的例程来一次执行数千次计算,而不是微函数。

Note that this is why DirectXMath is an all inline library that doesn't use indirect jump/dispatch at all. You can count on SSE/SSE2 always being supported for x64, and it's basically always supported for x86. If you happen to be building an EXE/DLL for a platform that always has AVX (such as Xbox One), then use /arch:AVX and the DirectXMath library will use AVX, SSE4.1, SSE3, SSE2/SSE where it makes sense. See this blog post series.