跨平台 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.
我最近对 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.