zoukankan      html  css  js  c++  java
  • 饱和运算的C/C++优化方案

    定义:

     

     所谓饱和运算(saturation),就是当运算结果大雨某个上限或是小于某个下限时,结果就等于上限或下限。

     

     

     

      饱和运算是图像处理中比较基本的运算,在图像的滤波、亮度增强、编解码等操作中都会遇到这个操作,所以研究如何用最优的方式运行该运算就很有意义了。

    由于我们最常见到的图像每个通道的位深为8比特,事实上我基本上没见过其他深度的。所以我们的讨论集中在如何优化8位图像的饱和运算。

    首先,我们知道作为一个基本运算,由于我们需要频繁地使用,所以对它会有更高的要求,因为基本运算性能的降低会成为整个系统性能的瓶颈。

    那么,一个好的运算算法的评价标准是什么呢?

    (1)       时间复杂度低

    (2)       空间要求少

       在这里,由于是作为内核的基本运算,所以我们对程序的可读性的要求会有所降低,毕竟鱼和熊掌不可兼得,我们需要有所割舍。

     

    So,我们看看有什么算法吧。首先,也是最容易想到的就是:

     方法一、刀耕火种法

       最直观的方法是根据定义来做。下面给出源码:

    Code

     

    我们分析一下这个程序,它很直观,但是未必高效,其原因是什么呢:

    (1)       对一个基本运算采用函数方式,增加了调用函数的时间开销。从c库函数的实现方式来看,一般基本操作需要优先考虑用宏定义的方式来解决,如getchar()等都是例证。

    (2)       采用了if-else if-else的分支结构,既增加了系统判断的时间开销,又由于需要比较而增加了系统的空间开销。

    i_pix > 255 语句

    汇编后的代码为:cmp  ecx,0FFh

    cmp指令是一个三字指令。

    说到这里,顺便提一下 i_pix < 0

    其汇编后代码为:test eax,eax

    test指令是一字指令,所以我们在做比较操作的时候如有可能尽量要与0比较。当然,这是题外话。

     

    以上两点提出了改进方向,一是尽量考虑用宏,二是考虑用比较运算符替代分支结构。

     

    下面的问题是:比较运算符只有两个比较条件,有没有可能把三个分支合并成两个分支呢?

    经过分析,我们发现一个现象:大于255和小于0的像素值偶一个共同特征,那就是,他们的高八位都是非零的。而且由于大于255的像素最后输出为25511111111),小于0的输出为000000000),与它们的符号相反,我们可以通过算术移位操作,把像素值的每位都填为符号位,然后再按位取反就行了。即,当pix越界时,输出为 ~(pix>>16) 或是(-pix>>16)就行了。

     

    关键问题解决了,下面的事就很简单了:

     #define saturation (pix) (((pix)&(~255))?(-(pix))>>16 : (UINT8)(pix))

     

      然后就进行测试:

     

    测试环境:

       操作系统: windows xp professional sp2

       CPUintel T2080 1.73Ghz

       内存:1.73Ghz, 504MB

       编译环境: VC++6.0

     

    我们随机生成了一个[-500500]范围内的150*1000的数组,在Release版本下的性能为:

     

      算法1 15 ms

      算法2 0 ms

     

    因为我们的作用对象是图像,一般规模都比较大,所以每幅图节约15ms还是很可观的。在视频条件下,按照每秒25帧的帧率来算的话,留给一帧的时间仅为40ms,这样看来节省15ms,算是很好的事了。

    后来又突然想到,给算法1的函数前加了inline,使之变为内联函数,跑出来的结果为:

      算法1 0 ms

      算法2 0 ms

    所以说在饱和运算的情况下,其实是函数调用对系统开销的影响最大,分支语句由于编译器的优化,所以已经不太占用系统开销了。

     

    得到一个结论,那就是:很多时候优化首先要从技术角度来考虑。但是,一个巧妙的新算法给我们带来的成就感更大。一个用于商业,一个用于兴趣,都有用。

    参考资源:

    1.百度百科

    http://baike.baidu.com/view/1547769.html?fromTaglist

    2. H.264 中很有用的一些概念

    http://hi.baidu.com/beily815/blog/item/09003c8d0c62271ab31bba46.html

  • 相关阅读:
    正则表达式
    简单的js拖动
    asp.net网站安全常见问题与防范
    Jquery操作select、checkbox、radio详细讲解
    利用ListView自定义高效分页
    文件上传
    Sql 分区问题
    封装读取配置文件类
    TypeConverter学习
    构造AJAX参数, 表单元素JSON相互转换
  • 原文地址:https://www.cnblogs.com/Matrix_Yao/p/1554583.html
Copyright © 2011-2022 走看看