Eigen';s矢量化后备工作?

Eigen';s矢量化后备工作?,eigen,simd,Eigen,Simd,报告说: 对SSE 2/3/4、AVX、FMA、AVX512、ARM NEON(32位和64位)、PowerPC AltiVec/VSX(32位和64位)指令集以及现在的S390x SIMD(ZVector)执行显式矢量化,并以优雅的方式回退到非矢量化代码 这是否意味着,如果您使用FMA进行编译,而您正在运行的CPU不支持它,那么它将退回到完全未经编译的代码?或者它会退回到可用的最佳矢量化吗 如果没有,有没有办法让Eigen为所有或多个SIMD ISA编译,并在运行时自动选择最佳的 编辑:我说的

报告说:

对SSE 2/3/4、AVX、FMA、AVX512、ARM NEON(32位和64位)、PowerPC AltiVec/VSX(32位和64位)指令集以及现在的S390x SIMD(ZVector)执行显式矢量化,并以优雅的方式回退到非矢量化代码

这是否意味着,如果您使用FMA进行编译,而您正在运行的CPU不支持它,那么它将退回到完全未经编译的代码?或者它会退回到可用的最佳矢量化吗

如果没有,有没有办法让Eigen为所有或多个SIMD ISA编译,并在运行时自动选择最佳的


编辑:我说的是运行时回退。

在Eigen中绝对没有运行时调度。所有发生的事情都发生在编译时。这是您需要通过C++编译器进行优化或设置的所有选择的地方。 为了实现运行时调度,您可能需要检查并查看每个对库的调用支持哪些CPU功能,并将其转移到适用的实现中,或者需要在启动时进行一次检查,并设置一个函数指针表(或其他一些有助于动态调度的方法)Eigen不能做后者,因为它是一个只有头的库(只是类型和函数的集合),没有“main”在初始化时调用的函数,其中所有的设置代码都可以本地化。因此,唯一的选项是前者,这将导致严重的性能损失。此库的整个要点是速度;将这种性能损失引入到每个库的函数中将是一场灾难

文档还包含。此页面显示:

本页的目标是了解Eigen如何编译它,假设启用了SSE2矢量化(GCC选项-msse2)

这进一步证实了静态编译时选项决定库如何工作的说法

无论选择哪个指令集作为目标,生成的代码中都会包含这些指令。如果您试图在不支持这些指令的处理器上执行该代码(例如,您在启用AVX优化的情况下编译Egen,但在不支持AVX指令集的英特尔Nehalem处理器上运行该代码),则您将获得无效的指令异常(以操作系统传递CPU异常的任何形式呈现给您的程序)。这将在您的CPU遇到无法识别/不受支持的指令时发生,该指令可能位于某个固有函数的内部(即启动时不立即出现)


然而,正如我在评论中所说,有一种回退机制,但它是一种静态机制,都是在编译时完成的。正如,Eigen支持多个向量指令集。如果您选择最低公分母指令集,如SSE2,您仍然会得到某种程度的向量化。例如,尽管SSE3可能提供特殊的对于某些特定任务,如果你不能以SSE3为目标,所有的希望都不会破灭。在许多地方,代码使用一系列SSE2指令来完成相同的任务。这些指令的效率可能不如SSE3可用,但它们仍然比没有矢量代码快。你可以通过挖掘int看到o源代码,特别是
arch
文件夹,其中包含针对不同指令集(通常通过使用内部函数)进行了专门优化的小贴士。换句话说,您可以获得针对目标体系结构/指令集的最佳代码。

鉴于此,“对于SSE,至少需要SSE2。SSE3、SSSE3和SSE4是可选的,如果启用,将自动使用。",我怀疑它会退回到可用的最佳矢量化选项。但仍然会有硬限制。例如,如果没有至少SSE2,则无法对双精度浮点运算进行矢量化。SSE仅支持单精度。我假设这就是报价中要求的原因。您可以在.t中看到这一点链接函数是为SSE优化的版本,您可以看到SSE3有一个实现,但如果没有,它会返回到只需要SSE2的版本。这是使用预处理器宏选择的,因此您需要确保这些宏定义正确。这些似乎是编译时预处理器指令。我说的是运行时回退。我看不到任何迹象表明,无论是在代码中还是在文档中,Eigen都支持任何类型的运行时分派/委派。你从哪里知道它支持?(但是,请注意,有些编译器支持这些功能,如Intel的C编译器。因此,由于这是一个只包含头的库,您可以使用其中一个编译器编译它,并可能获得运行时调度。)从我发布的引文中可以看出。如果它是关于运行时还是编译时,这是不明确的。这就是我问题的全部内容!!