SSE2加速DCT的试验

    视频压缩及解压缩,DCT是耗速大户,相对运算密集,试将运算部分由SSE2取代,以期提高运算速度。

原程序:耗时59us

void __fastcall CDCT::FDCT(double fOutPut[][8], double fInPut[][8])//正向离散余玄变换
{
   double tmp; int u,v,i,j;

   for(u = 0; u < 8; u++)
      {
        for(v = 0; v < 8; v++)
           {
             tmp = 0.0;
             for(i = 0; i < 8; i++)
             for(j = 0; j < 8; j++)
                {
                   tmp += fInPut[i][j] * C2[u][i] * C3[v][j];
                }
             fOutPut[u][v] = C4[u][v] * tmp;
           }
      }
}

替换程序:耗时140us

double double_Mul(double fD1, double fD2, double fD3)//
{
  double fRet;

  asm 
  {
    movsd XMM0, fD1  // XMM0 <- fD1
    mulsd XMM0, fD2  // fD1 = fD1 * fD2
    mulsd XMM0, fD3  // fD1 = fD1 * fD3
    movsd fRet, XMM0 // fRet <- XMM0
  }
  return fRet;
}

void __fastcall CDCT::FDCT(double fOutPut[][8], double fInPut[][8])//正向离散余玄变换
{
   double tmp; int u,v,i,j;

   for(u = 0; u < 8; u++)
      {
        for(v = 0; v < 8; v++)
           {
             tmp = 0.0;
             for(i = 0; i < 8; i++)
             for(j = 0; j < 8; j++)
                {
                   //tmp += fInPut[i][j] * C2[u][i] * C3[v][j];
                   tmp += double_Mul(fInPut[i][j], C2[u][i], C3[v][j]);//
                }
             fOutPut[u][v] = C4[u][v] * tmp;
           }
      }
}

使用SSE2竟然慢一倍多!为什么?经过多次采用不同形式的试验,虽然有改善,但谈不上提速,后来终于悟出了道理,解释如下:

1. 处理器增加了8个XMM寄存器,同FPU速度相同甚至低于FPU,XMM寄存器的优势是SIMD,如果一次处理一个数据,等同FPU处理速度,甚至不如FPU处理速度。

2. 以SIMD方式组织数据比较困难,格式要求特殊,运算特殊,程序结构容易混乱,不易使用。

3. 对于SSE2指令仅支持2个双精度浮点数,即使进行SIMD方式的2个双精度浮点数同时运算,也不一定带来一倍的提升效果,甚至不如没优化的。

4. 如果4个单精度浮点数以SIMD方式同时运算,可能有提升效果,SSE2指令支持4个单精度浮点数同时运算。

5. BCB6优化的很好,即使使用SSE2指令优化双精度浮点运算,也无济于事,可能还会弄巧成拙。

6. 当Code optimization选择Speed,DCT时提速6us。

这3天的努力是值得的,为多媒体加速爱好者提供了参考。

猜你喜欢

转载自www.cnblogs.com/hbg200/p/9159918.html
DCT
SSE