2015-07-06 31 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)你的编译器已经对标量进行了矢量化码。 –