我目前正在尝试运行一个简单的" max函数"循环扫描大量的uint_32值。
使用AVX2内在,它相当简单:
const __m256i limit8 = _mm256_set1_epi32(limit);
for (i=0; i<TABLESIZE; i+=8)
{
__m256i src = _mm256_loadu_si256((const __m256i*)(h+i));
src = _mm256_max_epu32(src, limit8);
_mm256_storeu_si256((__m256i*)(h+i), src);
}
唯一重要的操作是_mm256_max_epu32(vpmaxud),它可以有效地完成所请求的工作。表中的所有单元格都与单个常量进行比较。
现在,使用内在在可移植性方面有点限制,我宁愿使用标准C编写等效版本,编译器会自动对其进行矢量化。毕竟,内部循环看起来很简单,足以找到廉价的启发式算法。
唉,我没有通过这个简单的练习,即使VS2012关于自动矢量化的注释明确指出应该正确检测到这个功能:
我尝试过的事情:
for (i=0; i<TABLESIZE; ++i)
{
if (h[i]>limit) h[i]=limit;
}
不起作用:与食谱声明相反,&#34; if&#34;声明是这里的问题:auto-vectorize fails on code 1100
for (i=0; i<TABLESIZE; ++i)
{
h[i] = h[i] > limit ? h[i] : limit;
}
没有更好,尽管出于不同的原因:自动向量化fails on code 1304(循环包括不同大小的分配),这可能是一个错误,因为所有变量都使用相同的类型。
for (i=0; i<TABLESIZE; ++i)
{
const U32 val = ((limit-h[i]) >> 31);
h[i]-=limit; h[i]*=val; h[i]+=limit;
}
这个有效,并且是矢量化的。但它更复杂,因此比直接内在版本明显慢。
我想知道是否有办法让这个简单的&#34; max&#34;操作由Visual自动矢量化(GCC和Clang跟随)。