我有两个__m128i
s,a
和b
,我想要混淆,以便a
的高64位落在dst
的低64位{1}} b
的低64位落在dst
的高64位。即
dst[ 0:63] = a[64:127]
dst[64:127] = b[0:63]
相当于:
__m128i dst = _mm_unpacklo_epi64(_mm_srli_si128i(a, 8), b);
或
__m128i dst = _mm_castpd_si128(mm_shuffle_pd(_mm_castsi128_pd(a),_mm_castsi128_pd(b),1));
有没有比第一种方法更好的方法呢?第二个只是一条指令,但切换到浮点SIMD执行比第一条指令的额外指令更昂贵。
答案 0 :(得分:1)
延迟并不总是最糟糕的事情。如果它不是循环携带的dep链的一部分,那么只需使用单个指令。
此外,可能没有! Agner Fog的microarch doc说他在使用"错误"时发现在某些情况下没有额外的延迟。 Sandybridge上的shuffle或boolean类型。混合仍然具有额外的延迟。在Haswell,他说混合类型的洗牌没有额外的延迟。 (第140页,数据旁路延迟。)
所以继续使用shufps
,除非你非常关心你的代码在Nehalem上的速度很快。 (之前的设计(merom / conroe和Penryn)在使用错误的移动或随机播放方面没有额外的旁路延迟。)
对于AMD,shufps
在ivec域中运行,与整数shuffle相同,因此可以使用它。与英特尔一样,FP混合物在FP域中运行,因此FP数据没有旁路延迟。
如果您根据支持的指令集包含多个asm版本,而不必完全了解x264等每个CPU的最佳版本,那么您的版本可能会在AVX CPU中使用错误类型的操作,但是在非AVX版本中使用多个指令。 Nehalem有很大的惩罚(每个域转换有2个周期旁路延迟),而Sandybridge是0或1个周期。 SnB是AVX的第一代产品。
Pre-Nehalem(没有SSE4.2)太老了,可能不值得为它专门调整版本,即使它没有对#34;错误的类型&#进行任何处罚34;洗牌。 Nehalem正处于有点慢的尖端,因此在这些系统上运行的软件将是最难以实时操作的,或者感觉不慢。因此,在Nehalem上做坏事会增加糟糕的用户体验,因为他们的系统已经不是最快的了。