我有一些代码,一次在3个对称集的3个不对称整数值上操作。有大量的条件代码和许多常数。
这已成为一个完美的瓶颈,我正在寻找一些经验法则,因为Simd在64位Intel/AMD CPU上会带来perf perf Fin。该代码很长,我以前从未使用过SSE2或AVX,因此很高兴有一定的想法,即在我投入时间之前是否可能获胜或可能。
如果您愿意列出经验规则或指向现有的白皮书,我将不胜感激。
SSE标签Wiki有几个向量化的指南,包括这些谈话中的幻灯片,这些幻灯片本身是可以理解的,这些幻灯片具有一些很好的例子,可以将数据结构转换为启用矢量化(和经典)例如将[x,y,z,w]
几何向量放入单个SIMD向量之类的陷阱)。
SIMD的经典用例是在有很多独立操作时,即环路内没有串行依赖,例如z[i] = d * x[i] + y[i]
。或者,如果有,则只能使用可让您重新订购的关联操作。(例如,求和阵列或类似的还原)。
也很重要的是,您可以做到这一点,而无需大量改组;理想情况下,您的所有数据在从连续内存中加载后在向量中"垂直"对齐。
对于相邻元素的多种条件通常对SIMD不利。这需要无分支的实施,因此您必须完成每个分支两侧的所有工作,并合并。除非您可以检查矢量中的所有4个(或所有16个或其他)元素,以相同的方式
即使您可能没有期望,也可以将某些东西矢量化,因为它们是通常的经验法则的例外。例如将IPv4点列字符串转换为32位IPv4地址,或将小数位数转换为整数,即实现atoi()
。这些通过巧妙地使用多种不同的技巧来进行矢量化,包括带有矢量 - 包装位图作为LUT的索引的PSHUFB的查找桌面。
因此,一旦知道了一些技巧,就总是根据一些经验规则来快速排除矢量实现。即使是串行依赖性有时也可以解决,例如SIMD前缀总和。