Automatically use AVX/SSE if available at runtime?

时间:2016-07-11 22:54:19

标签: c++ visual-c++ avx

Dupe of Have different optimizations (plain, SSE, AVX) in the same executable with C/C++

The "Auto-duplicate" think picked the wrong suggested duplicate, and I don't seem to have the interface to fix it.


Is there any way to build a application that will optionally use instruction set extensions if available, and yet still function (albeit more slowly) in their absence?

Right now, I have a MSVC++ radar imaging application that does a lot of math that can benefit from vectorization. If I compile the application with AVX, it then crashes at application start when run on a platform missing those CPU functions.

Is there any way to have the compiler generate both AVX accelerated and normal instructions, and switch between them at runtime? It seems like the only other option is to have two complete builds of the application, and chose which to install based on the CPU architecture, but that sounds like more trouble then it's worth.

1 个答案:

答案 0 :(得分:3)

至少我知道的编译器没有,他们不会生成代码来自动检测并自动利用可用的指令集(至少从完全可移植的代码中看 - 见下文更多)。

与应用程序的两个完整版本不同,将应用程序的数字,CPU密集型部分移动到DLL中,并且只在运行时选择它们通常是有意义的。这样,UI和类似的东西(不会从特殊指令中获益)就生活在一个公共区域,只有少数你关心的特定部分会在运行时被切换出来。

由于您标记了C ++,我将提到一种管理此方法的可能方法:定义一个定义数值例程接口的抽象基类。然后为您关心的每个指令集定义派生类。

然后在运行时,你有一个指向基础的指针。初始化代码检查可用的CPU,并初始化该指针以指向正确类型的派生对象的实例。从那时起,您只需通过该指针与例程进行交互。

为了避免增加过多的开销,你通常想要在那个类(或者那些类,视情况而定)中定义你的函数,以便每个人做相当多的工作,以分摊虚拟函数的增加成本打电话给更多的工作。

你通常不必参与直接打电话LoadLibrary这样的事情。您可以使用/Delayload链接器标志告诉它仅在您实际调用DLL中的函数时加载DLL。然后,只会加载与您实例化的派生类相对应的DLL。

另一个明显的可能性是使用像Cilk Plus这样的库/编译器扩展来管理大部分的矢量化。有了这个,您可以(例如)编写如下内容:

a[:] = b[:] + c[:];

...得到大致相当于的东西:

for (int i=0; i<size; i++)
    a[i] = b[i] + c[i];

编译器链接到Cilk Plus库,该库处理检查CPU支持的指令集,并在适当时使用它们。