Clang 用于矩阵向量计算的铿锵优化标志

Clang 用于矩阵向量计算的铿锵优化标志,clang,glm-math,Clang,Glm Math,我查看了由glm(用于3d计算的矩阵向量库)操作的clang生成的反汇编代码 我注意到clang对双精度运算进行了一些“矢量化”,例如,在一条SIMD指令中强制执行两次乘法 然而,对于单精度计算,代码对我来说似乎不好。使用的指令来自SSE指令集和寄存器MMX指令集,但每次执行一个浮点数的多重应用程序,甚至一组赋值(如矩阵赋值)都是由大量movss语句执行的。这些糟糕的赋值甚至适用于双精度代码 为什么会这样,有没有任何命令行参数可以促使clang做得更好?我知道编译器并没有什么神奇之处,但我想16

我查看了由glm(用于3d计算的矩阵向量库)操作的clang生成的反汇编代码

我注意到clang对双精度运算进行了一些“矢量化”,例如,在一条SIMD指令中强制执行两次乘法

然而,对于单精度计算,代码对我来说似乎不好。使用的指令来自SSE指令集和寄存器MMX指令集,但每次执行一个浮点数的多重应用程序,甚至一组赋值(如矩阵赋值)都是由大量movss语句执行的。这些糟糕的赋值甚至适用于双精度代码


为什么会这样,有没有任何命令行参数可以促使clang做得更好?我知道编译器并没有什么神奇之处,但我想16个内存相邻分配的线性列表应该可以在许多方面进行优化?

在汇编读取xmm寄存器中并不是矢量化的证明,因为现在每个双精度操作都在SIMD寄存器中执行(甚至是单精度)

矢量化对于编译器来说并不是一件小事,clang提供了类似这样的选项

clang -fslp-vectorize-aggressive file.c

它可能会有帮助,否则你可能会寻找替代品,它有很多矩阵乘法库,MKL库,boost numeric库,plasma库,等等。。。在我的纪念品中,GLM是旧的,存在好的替代品。

你说得对,xmm寄存器用于单个操作。另一方面,对于双精度运算,实际上使用了两个通道运算。所以我猜我会看到单精度的四通道操作,但不是,更糟。我快速查看了GLM(),如果它是这个库,根据经验,SIMD计算只在大缓冲区上运行良好,而不是在处理一小段数据时(如果你有一个顶点列表,你永远不会用SIMD保存某些内容)。此外,您是否尝试使用mem align分配器(),我没有顶点数据的集合(例如列表),但堆栈上有一些矩阵或顶点。然而,通过矩阵积得到的每个向量通过SIMD都应该有很好的增益,因为它已经由64个浮点乘法和一系列加法组成。如果其中四个可以在一个步骤中完成,则可以预期4倍的增益。由于堆栈上没有集合,但有许多操作,缓存应该是热的,不应该限制工作。GLM也有一些本机SIMD实现,但这些实现依赖于需要从普通数据类型转换而来的特殊数据类型,并且只有一些操作是可能的。如此往复的转换会消耗掉所有的好处。你给了内存对齐的提示,也许编译器需要手动提示来对齐基于堆栈的短寿命SIMD结构?