2013-05-08 21 views
1

所以我使用SSE2該樓層的向量寫了一個函數,但它似乎只對例如它工作正常,我的雙線性過濾算法,但用於執行模時,某些目的的工作它出現稍微偏離的值。該函數通過使用截斷對整數向量執行轉換並將其轉換回浮點來工作。無論是地板和模代碼列舉如下:我SSE2地板的功能有一些問題

inline __m128 floor_SIMD(const __m128 & a) 
{ 
    __m128i int_val = _mm_cvttps_epi32(a); 
    return _mm_cvtepi32_ps(int_val); 
} 

inline __m128 mod_SIMD(const __m128 & x, const __m128 & y) 
{ 
    return _mm_sub_ps(x, _mm_mul_ps(y, floor_SIMD(_mm_div_ps(x, y)))); 
} 

也許人有一個解釋,爲什麼我從我的模越來越有點奇怪的價值? (_mm_set1_ps(63.6f),_mm_set1_ps(32.0f))會產生錯誤答案,但是mod_SIMD(_mm_set1_ps(23.6f),_mm_set1_ps(32.0f))會產生一個正確的答案回答。當我用更低效的組件智能版本替換地板功能時,它可以正常工作。

+2

您能提供示例代碼來重現問題嗎? – 2013-05-08 18:20:49

+0

是的MOD功能是與問題的代碼。它適用於小於y的每個值,但如果它超過y則失敗。我會發佈一個示例用法。 – PgrAm 2013-05-08 18:33:11

+2

'它會產生一個錯誤的答案' - 那是什麼答案? – anatolyg 2013-05-08 18:47:00

回答

3

我解決了我自己的問題。爲了大家的利益,這裏是我的結果代碼。如果它的值大於補償截斷問題的原始值,它會從該值中減去一個值

inline __m128 floor_SIMD(const __m128 & a) 
{ 
    static const __m128 one = _mm_set1_ps(1.0f); 

    __m128 fval = _mm_cvtepi32_ps(_mm_cvttps_epi32(a)); 

    return _mm_sub_ps(fval, _mm_and_ps(_mm_cmplt_ps(a, fval), one)); 
} 
+1

這個版本還是有問題的;它會給你floor(-1)= -2,這是你不想要的。相反,如果'a 2013-05-10 19:05:06

+0

@StephenCanon哎呀,我想我沒有測試不夠徹底我編輯的代碼對你的建議,現在工作正常。答案也已被編輯。 – PgrAm 2013-05-10 19:09:16