Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C SSE2饱和算法_C_Sse_Simd_Intrinsics_Sse2 - Fatal编程技术网

C SSE2饱和算法

C SSE2饱和算法,c,sse,simd,intrinsics,sse2,C,Sse,Simd,Intrinsics,Sse2,我正在写一些音频处理软件,我需要知道如何用SSE2双精度指令进行饱和运算。我的值需要在-1和1之间标准化。有没有一种聪明的方法可以利用SSE2内在函数实现这一点,或者我需要两组if/else语句(每个值一个) 要将双精度值剪裁到-1.0到+1.0的范围,可以使用最大/最小操作。例如,如果您有一个缓冲区,buff,具有N个双值: const __m128d kMax = _mm_set1_pd(1.0); const __m128d kMin = _mm_set1_pd(-1.0); for (

我正在写一些音频处理软件,我需要知道如何用SSE2双精度指令进行饱和运算。我的值需要在-1和1之间标准化。有没有一种聪明的方法可以利用SSE2内在函数实现这一点,或者我需要两组if/else语句(每个值一个)

要将双精度值剪裁到-1.0到+1.0的范围,可以使用最大/最小操作。例如,如果您有一个缓冲区,
buff
,具有N个
值:

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);
}
const\uuuum128d kMax=\umm\uset1\upd(1.0);
常数m128d kMin=_mm_set1_pd(-1.0);
对于(int i=0;i
为什么要对音频使用双精度?无论如何,在最终转换回您正在使用的任何音频格式之前,您实际上不需要饱和,在这一点上,您可以使用饱和包指令(如果是整数格式)或max/min指令(如果要显式执行)。音频格式可以作为int32、int64、float32、,和浮动64。我现在正好在做float64部分。好的-然后使用max/min操作-见下面的答案…很好!那真的很有趣。谢谢你的帮助哇…我刚刚发现了一些非常有趣的东西。所有的内在功能都使它变慢了。我用得越多,速度就越慢。仅使用原语类型(双重),我在1738纳秒内完成了500000个加法运算。仅将SSE2用于加法,我得到了5198纳秒。根据上面的答案,我得到了31888纳秒。那对我来说毫无意义。不过看看反汇编,他们使用了xmm寄存器。这可能是因为编译器在做所有事情时都知道如何更好地优化它吗?有两种可能的解释:(1)您使用的是调试构建非优化(即
-O0
)来计时,而不是发布构建(
-O3
)和/或(2)您的编译器已经对标量代码进行了矢量化。我正在使用Visual Studio,我编译的目的是最大限度地提高速度。我相信这是对代码进行矢量化。如果你在缓冲区上做一个单独的传递,使其达到最小/最大值,而不是在你的常规计算程序结束时,当值已经在矢量寄存器中时,进行传递,那么速度会慢一些。(特别是如果你在比二级缓存大的块中工作。)我猜你可能是在使用内部函数,迫使编译器存储到mem,然后加载,或者类似的方式。通常,让自动矢量器做好工作是最好的选择。当你需要巧妙的洗牌时,更需要使用内在的自我。