Enz*_*nzo 12 c++ sse matrix-multiplication
我需要每秒运行240000次矩阵向量乘法.矩阵是5x5并且始终相同,而向量在每次迭代时都会发生变化.数据类型是float.我正在考虑使用一些SSE(或类似)指令.
1)我担心算术运算的数量与所涉及的存储器操作的数量相比太小.你认为我可以获得一些有形的(例如> 20%)改善吗?
2)我需要英特尔编译器吗?
3)你能指出一些参考文献吗?
谢谢大家!
小智 5
原则上,SSE 的加速可以是 4 倍(AVX 的 8 倍)。让我解释。
让我们称您为固定的 5x5 矩阵M。将 5D 矢量的分量定义为 (x,y,z,w,t)。现在从前四个向量 形成一个 5x4 矩阵U。
U =
xxxx
yyyy
zzzz
wwww
tttt
Run Code Online (Sandbox Code Playgroud)
接下来,做矩阵乘积MU = V。矩阵V包含M和前四个向量的乘积。唯一的问题是,对于 SSE,我们需要读取U的行,但在内存中U存储为xyzwtxyzwtxyzwtxyzwt所以我们必须将其转置为xxxxyyyyzzzzwwwwtttt。这可以通过 SSE 中的 shuffle/blends 来完成。一旦我们有了这种格式,矩阵乘积就会非常有效。
与使用标量代码进行 O(5x5x4) 操作不同,它只需要 O(5x5) 操作,即 4 倍加速。使用 AVX,矩阵U将是 5x8,因此它不会进行 O(5x5x8) 运算,而是只对 O(5x5) 征税,即 8 倍加速。
但是,矩阵V将采用xxxxyyyyzzzzwwwwtttt格式,因此根据应用程序,它可能必须转换为xyzwtxyzwtxyzwtxyzwt格式。
对接下来的四个向量(AVX 为 8 个)重复此操作,直到完成。
如果您可以控制向量,例如,如果您的应用程序动态生成向量,那么您可以以xxxxyyyyzzzzwwwwtttt格式生成它们并避免数组的转置。在这种情况下,您应该使用 SSE 获得 4 倍的加速,使用 AVX 获得 8 倍的加速。如果将此与线程(例如 OpenMP)结合使用,则使用 SSE 的加速应该接近 16 倍(假设有四个物理内核)。我认为这是你可以用 SSE 做的最好的事情。
编辑:由于指令级并行性 (ILP),您可以获得 2 倍的加速,因此 SSE 的加速可以在四核 (64x AVX) 下提高 32 倍,而由于 FMA3,Haswell 的加速又是 2 倍。