曾几何时,当我的编译原理还在60分上下徘徊的时候,我从未想过,会有一天,我会用avx指令写程序,然后一脚踏入-march=native这个神坑。
毕竟,当初的编译原理课,我一共就学会了两个命令
一个叫-O3
,一个叫-march=native
凭借这两个命令,我把手里的程序加速加速再加速……从未翻车——直到某日我发现电脑CPU不够多——于是,我找老板借了服务器……一台Centos服务器
灾难……降临了
在揭晓答案之前,我想先附一段会随机崩溃的程序:这是一个用fma(每一个函数都是查Intel Intrinsics Guide找到的)写的矩阵乘法,大概就是R语言用.Call调用MmV,MmV调用matmul,然后matmul调用真正干活的mmv,matmul到mmv这里用到了循环展开的技巧,把mat先分段,然后每段执行mmv(比如说{ {a1,a6,a11},{a2,a7,a12},{a3,a8,a13},{a4,a9,a14},{a5,a10,a15}},此时vec是一个3维的向量{v1,v2,v3},我们希望得到结果{a1v1+a6v2+a11v3,a2v1+a7v2+a12v3,...}——这时候我们把mat拆成两部分,一部分长度是4的倍数,另一部分是剩下的,实验&Guide证明,mmv可以处理4的倍数,于是第一种情况解决,对于第二种情况,我们可能会多读几个double数据,不过没关系,为了这玩意我贴心地算了一个mask出来,不管mmv算出来的是什么鬼ÿ