自动使用 AVX/SSE(如果在运行时可用)
Automatically use AVX/SSE if available at runtime?
Dupe of 在同一个可执行文件中使用 C/C++ 具有不同的优化(普通、SSE、AVX)
"自动复制"认为选择了错误的建议重复,我似乎没有界面来修复它。
有没有办法构建一个应用程序,该应用程序可以选择使用指令集扩展(如果可用),但在没有指令集扩展的情况下仍然可以运行(尽管速度更慢)?
现在,我有一个 MSVC++ 雷达成像应用程序,它可以做很多数学运算,可以从矢量化中受益。如果我使用 AVX 编译应用程序,那么当在缺少这些 CPU 功能的平台上运行时,它会在应用程序启动时崩溃。
有没有办法让编译器同时生成 AVX 加速指令和普通指令,并在运行时在它们之间切换?似乎唯一的其他选择是拥有两个完整的应用程序版本,并根据 CPU 架构选择要安装的版本,但这听起来比它值得的麻烦更多。
至少对于我知道的编译器,不,它们不会生成代码来自动检测和利用可用的指令集(至少从完全可移植的代码 - 请参阅下文了解更多信息)。
通常,将应用程序的数字、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 支持的指令集,并根据需要使用它们。
- C++代码在 for 循环的条件下给出运行时错误,而如果它被具有相同意义的代码替换,则编译正确
- 从库中发出信息,而无需运行时成本(如果不需要)
- 如果C++编译为机器代码,为什么我们需要安装"运行时"?
- 如果在C 程序中使用OpenMP,请在运行时检测
- 如果给定正确的运行时库,x86 可执行文件是否可以在任何 x86 平台上运行
- 在C程序中,如果在运行时忽略语句
- 如果应用程序仅针对 armv7 和 armv7 编译,则在 arm64 设备上运行时,它使用什么大小的数据类型
- 如果没有运行时错误,我无法从MYSQL_ROW转换为System::String类型
- 程序在第一次运行时正确地找到了最大值和最小值,但如果我再次运行,它会给我错误的答案
- 如果在其他线程仍在运行时调用exit(0),会发生什么情况
- 如果可能,尝试对字符串执行静态断言,或者在不是时回退到运行时检查
- 如果ISR运行时发生中断会发生什么
- 如果你的程序在运行时几乎立即退出,如何确保控制台窗口保持打开状态以读取输出
- 如果指针可以在运行时动态地改变数组的大小,为什么有必要用size初始化数组呢?
- 如果在保持相同类型的同时添加constness, static_cast运行时开销是多少?
- 如果lambda在运行时被移动/销毁,会发生什么
- 为什么如果 QWidget 在屏幕上不可见,我只能在运行时向 QWidget 添加元素?
- 在运行时可以检测到C++03和C++11之间的差异(如果有的话)
- 自动使用 AVX/SSE(如果在运行时可用)
- 如果使用 malloc 存储 STL 列表的分配内存,则运行时错误即将到来