2011-07-03 68 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商店。 –