3

我已经为 Windows 开发了一个 Mandelbrot 生成器,我刚刚转换为使用 SSE Intrinsics。为了检测迭代的结束,在正常的算术中我做了一个大于比较和突破。在 SSE 中执行此操作我可以使用 _mm_cmpgt_pd/_mm_cmpgt_ps 对整个向量进行比较,但是对于我关心的情况,这将写入一个全为 1 的新 128 位向量。

我的问题是,有没有一种更有效的方法来检测所有 1,而不是检查 2 个打包的 64 个 INT?或者,如果检测所有 0 更有效,那么我可以比较小于。这是我目前拥有的:

_m128d CompareResult = Magnitude > EarlyOut;
const __m128i Tmp = *reinterpret_cast< __m128i* >( &CompareResult );
if ( Tmp.m128i_u64[ 0 ] == Tmp.m128i_u64[ 1 ] == -1 )
{
    break;
}

我想找到更好方法的原因是因为我不喜欢演员阵容,还因为根据 vTune,我 30% 以上的迭代时间都花在了最后一行上。我知道其中很多将在分支本身中,但我认为我可以通过更好地检测 0 或 1 来减少这种情况。

谢谢

4

1 回答 1

6

假设您正在测试比较的结果,那么您可以将每个字节的 MS 位提取为 16 位整数并进行测试,例如

int mask = _mm_movemask_epi8((__m128i)CompareResult);
if (mask == 0xffff)
{
    // compare results are all "true"
}

请注意,这是 SSE 中 SIMD 谓词的更通用技术的一个示例,即

mask == 0xffff // all "true"
mask == 0x0000 // all "false"
mask != 0xffff // any "false"
mask != 0x0000 // any "true"
于 2013-04-15T15:21:56.347 回答