我已经为 Windows 开发了一个 Mandelbrot 生成器,我刚刚将其转换为使用 SSE Intrinsics。为了检测迭代的结束,在正常的算术中,我做了一个大于比较和突破的操作。在 SSE 中执行此操作,我可以使用 _mm_cmpgt_pd/_mm_cmpgt_ps 对整个 vector 进行比较,但是对于我关心的情况,这将写入一个全为 1 的新 128 位 vector 。
我的问题是,是否有比检查 2 个打包的 64 INT 更有效的检测所有 1 的方法?或者,如果检测所有 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 来减少它。
谢谢
最佳答案
假设您正在测试比较的结果,那么您可以将每个字节的 MS 位提取为 16 位 int 并对其进行测试,例如
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"
关于c - SSE 内部函数 : Fastest way to test for all 0s or 1s?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16017171/