图像分析中常见的使用Conditional Remove的优化类型(1):Array Clip

来源:互联网 发布:汇易宝网络借贷 编辑:程序博客网 时间:2024/06/04 19:03

就是把某个区间的灰度值映射到一高一低两个极值(经验证,除了赋值之外亦可做一些简单计算),剩下来中间的做某种处理,比如加、减、乘、除或者绝对值、移位什么的。典型的代码如下:

Intel C++ Compiler通过Conditional Remove(利用比较生成掩码,再加上一下逻辑操作)对此种类型进行自动向量化。

不过经过试验发现,ICC目前(Windows 版 11.1)只支持源数据为signed的自动向量化。究其原因,是因为simd指令中只有支持signed型数据的比较,即pcmpgtb/pcmpgtw/pcmpgtd,没有支持unsigned类型比较的指令。关于这一点,当初隐约觉得有可能是缺指令,但是一直不敢肯定。
主要是觉得,ICC可以智能地把unsigned的数据提升到更宽类型的signed类型数据进行向量化操作(当然安全性不能保证)。
或者使用Igor M. Levicki介绍的方法:pcmpeqw + paddusw + psubusw + paddw
http://software.intel.com/en-us/articles/array-clipping/


今天上网查了一下,观点得到Aart J.C. Bik大牛的确认。
http://software.intel.com/en-us/forums/showthread.php?t=46566

"Dear user,
The reason the first loop is vectorized with 8-way SIMD parallelism on packed words but not the second is due to the lack of support for a packed unsigned ">"comparison (viz. instruction pcmpgtw supports ">"comparisons on packed signed words, but not for packed unsigned words). In contrast, a "=="or "!=" comparison will vectorize for both cases, because the instruction pcmpeqw (possibly negated) works for both packed signed and unsigned words (provided that both operands are consistently either sign extended or zero extended, as in your example, so that the comparison can be done in the narrower 16-bit precision to allow for maximum parallelism).”
第一个循环能够以打包字的方式八路SIMD并行进行向量化,而第二个循环不能的原因在于:缺乏没有指令支持打包无符号字的“>”比较(指令pcmpgtw只支持打包有符号字的“>”比较,并不支持打包无符号字的“>”比较)。与此相对应的是, "=="or "!="操作均能顺利向量化。因为指令pcmpeqw不仅支持打包的有符号字,还支持打包的无符号字(符号两边的操作数类型需要一致)。所以求maximun值的并行化能够以窄16位的精度进行。(Lychee注:对于等号、不等号的已经验证过,确实有符号和无符号都能自动向量化)

原创粉丝点击