2015-07-06 32 views
3

我正在寫一些音頻處理軟件,我需要知道如何使用SSE2雙精度指令來進行飽和運算。我的值需要在-1和1之間進行歸一化。有沒有一種聰明的方法可以用SSE2內在的方式來做到這一點,或者我需要2組if/else語句(每個值有一個)?SSE2飽和算術

+1

爲什麼你甚至使用雙精度音頻?無論如何,直到你最終轉換成你正在使用的任何音頻格式,你都不需要飽和,此時你可以使用飽和包指令(如果是整數格式)或最大/最小指令,如果你想做它明確。 –

+0

那麼音頻格式可以作爲int32,int64,float32和float64處理。我恰好現在正在做float64部分。 –

+0

確定 - 只需使用最大/最小值操作 - 請參閱下面的答案... –

回答

4

要將雙精度值裁剪到-1.0到+1.0的範圍,可以使用最大/最小操作。例如。如果你有一個緩衝,buff,N double值:

const __m128d kMax = _mm_set1_pd(1.0); 
const __m128d kMin = _mm_set1_pd(-1.0); 

for (int i = 0; i < N; i += 2) 
{ 
    __m128d v = _mm_loadu_pd(&buff[i]); 
    v = _mm_max_pd(v, kMin); 
    v = _mm_min_pd(v, kMax); 
    _mm_storeu_pd(&buff[i], v); 
} 
+0

好!這真的很有趣。感謝您的幫助 –

+0

哇......我剛剛發現了一些非常有趣的東西。所有的內在功能使其變慢。我越用越慢。僅使用原始類型(雙精度),我在1738納秒內完成了500000次加法運算。使用SSE2僅用於添加,我得到了5198納秒。使用上面的答案我得到了31888納秒。這對我來說毫無意義。儘管如此,他們使用了xmm寄存器。難道這是事實:編譯器知道如何更好地優化它,當它做的一切? –

+0

兩種可能的解釋 - (1)你使用的調試版本沒有優化(即'-O0')而不是發佈版本('-O3')和/或(2)你的編譯器已經對標量進行了矢量化碼。 –