2011-07-03 45 views
7

我一直在努力优化一些代码,我使用微软的sse intrinsics。优化我的代码时最大的问题之一是每当我想使用常量时发生的LHS。似乎有一些关于生成某些常量(herehere - section 13.4)的信息,但它的所有程序集(我宁愿避免)。不断漂浮SIMD

问题是,当我尝试用intrinsics实现相同的事情,msvc抱怨不兼容的类型等。有谁知道使用intrinsics的任何等价技巧?

实施例 - 生成{1.0,1.0,1.0,1.0}

//pcmpeqw xmm0,xmm0 
__m128 t = _mm_cmpeq_epi16(t, t); 

//pslld xmm0,25 
_mm_slli_epi32(t, 25); 

//psrld xmm0,2 
return _mm_srli_epi32(t, 2); 

这产生一串大约不兼容的类型(__m128 VS _m128i)错误。我很新,所以我很确定我错过了一些明显的东西。谁能帮忙?

tldr - 如何生成充满了与MS内在单精度浮点数不变的__m128 VEC?

感谢您的阅读:)

+0

是什么让你觉得你需要这样做?在计算循环之前,通常只加载一次常量,因此内存访问的相对成本可以忽略不计。 –

+0

我有几个常量,所有这些都在一个循环中使用,不幸的是,它似乎已经使用了所有8 xmm寄存器。在vtune内,在使用其中一些常数时,我得到了非常高的CPI。我想,如果我可以减少我正在访问的常量的数量,并且生成一些常量,那么可以降低成本,因为可以隐藏另一个的成本。另外,奇怪的是,在其中一个常量上使用register关键字有一点帮助(尽管这只是导致其他值被推出xmm regs)。 – JBeFat

+4

如果可以的话,使用x86-64 - 这样你可以得到16个XMM寄存器。还要注意的是,即使您第一次加载这些常量时发生一个或多个缓存未命中,应该在大量迭代中分配常量,然后将常量放入L1缓存中。 (除非你只有少量循环迭代?) –

回答

3

只需使用_mm_castsi128_ps将__m128i投射到__m128即可。另外,第二行应该是

t = _mm_slli_epi32(t, 25) 
+0

谢谢!我有一种感觉,它会是这样简单的事情。 – JBeFat

4
+0

'0x1a11 MOVAPS xmm6,xmmword PTR [0x414890]'' 0x1a18 xorps xmm5,xmm5' 您好,感谢您抽出时间来回答:)你可以从(格式错误,对不起)见上面列出的__mm_set_ps对我没有帮助,因为它仍然使用movaps从内存中的某处加载常量。我想要的是使用现有的方法直接在xmm寄存器中生成常量。 – JBeFat

+0

@JBeFat:你试过简单地输出结果吗?这些技巧使用整数指令来创建浮点值,所以我不觉得编译器会抱怨类型不匹配。 –

+1

另请注意,由于不涉及FPU,因此不存在带'__mm_set_ps'的LHS商店。 –