xxb 发表于 2007-8-14 09:36:00

MMX版本的Alpha Blend算法实现

<font face="Tahoma" size="2">这次我们的目标是: 超越普通的CPU玩家,用CPU的母语来优化程序!</font>
        <p><font face="Tahoma" size="2">实验器材:VC++ 4.2以上的编译器或C++ Builder 4.0以上编译器</font></p><p><font face="Tahoma" size="2">MMX技术到现在来说可以算是基本大众化了,目前大多数个人电脑都应该能支持它。P55C,K6,PII,PIII...按照惯例,Intel公司将在以后的x86版本永远支持它。</font></p><p><font face="Tahoma" size="2">要了解MMX指令体系,请一定浏览以下URL,获得系统的MMX体系知识:</font></p><p><a href="http://www.game1st.com/database/mmxd/mmxd.htm" target="_blank"><font face="Tahoma" size="2">http://www.game1st.com/database/mmxd/mmxd.htm</font></a></p><p><font face="Tahoma" size="2">否则将会对我的讲解摸不着北,(象听最优控制或者线性控制理论一样)</font></p><p><font face="Tahoma" color="#009933" size="2">提示:最好自己多写些Console App来实验和熟悉MMX指令特性,cout出结果,不要一来就搞Windows App.</font></p><p><font face="Tahoma" size="2">MMX技术的优点是什么?</font></p><p><font face="Tahoma" size="2">一言蔽之,就是<font color="#ff0000">一个指令操作多个整型数据</font>.并且可以<font color="#ff0033">自动完成饱和运算</font>。</font></p><p><font color="#3333ff"><font face="Tahoma" size="2">MMX最适合的应用领域是数字图象处理</font></font><font face="Tahoma" size="2">,然后是语音,通讯等领域。</font></p><p><font face="Tahoma" size="2">写图象处理算法时很影响效率的以下几点是:</font></p><p><font face="Tahoma" size="2">1.不厌其烦的低效邻域操作: 不厌其烦的写GfxBuffer,GfxBuffer,GfxBuffer,...取RGB值等。</font></p><p><font face="Tahoma" size="2">2.恼人的环绕:</font></p><p><font face="Tahoma" size="2">像素运算溢出,必须拿个大点的数据类型来保存结果再判断溢出,否则结果就是错误的</font></p><p><font face="Tahoma" size="2">short int GfxOut=GfxBuf1+GfxBuf2; ...</font></p><p><font face="Tahoma" size="2">if(GfxOut&gt;255)GfxOut=255; if(GfxOut&lt;0)GfxOut=0;</font></p><p><font face="Tahoma" size="2">问题是你知道那两个判断回会生成多少汇编代码吗?</font></p><p><font face="Tahoma" size="2">3.不必要的高精度: 该死的RGB-&gt;YUV运算,我们最熟悉的彩色转灰度运算: Y=(BYTE)(Red*0.299+Green*0.587+Blue*0.114);</font></p><p><font face="Tahoma" size="2">其实我们关心的是一个字节结果,谁愿意让协处理器做大量运算,得到float结果,还要再转换为byte结果呢?要知道IEEE浮点转整数可不象在C程序里看起来那么简单!(在你为51单片机这种低级的劣质的没有协处理器的CPU写过程序就知道了...)代价是相当大的。</font></p><p><font face="Tahoma" size="2">尤其图面比较大的情况下,你会在屏幕面前等得生霉,我们不要那么高的精度啊。</font></p><p><font face="Tahoma" size="2">而MMX技术就是黑暗中的灯塔,被老板咒骂的程序员的救命稻草,使图象处理模式识别和神经网络专业方向的研究生不被导师训斥的的葵花宝典...(本人不系Intel中国公司的营销部经理啊..)</font></p><p><font face="Tahoma" size="2">以32-bit为例,下面具体讲下用简单的例子讲解MMX技术优化北航老王头提供的Alpha Blend算法:</font></p><p><font face="Tahoma" size="2">绝对为本人在某个深夜所原创,不抄袭自任何资料</font></p><p><font face="Tahoma" size="2">char *pSrc,*pOvr; { pSrc=pScanline1+j; pOvr=pScanLine2+j; j+=4; .....</font></p><p><font face="Tahoma" size="2">假定我们的源像素在pSrc,覆盖图Overlay在pOvr,各指向一个32 bit像素。</font></p><p><font face="Tahoma" size="2">( 为什么要以32bit像素?因为老赫有两年做字幕卡程序的背景,电视字幕是32 bit图文层嘛! )</font></p><p><font face="Tahoma" size="2">如果你阅读了开始我提供的URL文档,你就清楚,MMX有八个64bitRegister,叫MM0-&gt;MM7,是浮点处理器的别名,也是他们的低64位映象。</font></p><p><font face="Tahoma" size="2">__asm{ pxor mm2,mm2 //把MM2清0</font></p><p><font face="Tahoma" size="2">mov edx,dword ptr //取32bit像素地址到edx</font></p><p><font face="Tahoma" size="2">movd mm0,dword ptr //把Source像素取到mm0低32bit</font></p><p><font face="Tahoma" size="2">mov edx,dword ptr </font></p><p><font face="Tahoma" size="2">movd mm1,dword ptr //把32 bit Overlay像素取到mm1低32bit</font></p><p><font face="Tahoma" size="2">punpcklbw mm0,mm2 //Source:8 bit到16 bit以容纳结果,32bit expand to 64 bit</font></p><p><font face="Tahoma" size="2">punpcklbw mm1,mm2 //Overlay:8 bit到16 bit以容纳结果.32bit expand to 64 bit</font></p><p><font face="Tahoma" size="2">movq mm3,mm1 // 因为要用Overlay的Alpha值</font></p><p><font face="Tahoma" size="2">punpckhwd mm3,mm3 // 高字移动到双字</font></p><p><font face="Tahoma" size="2">punpckhdq mm3,mm3 // 双字移动到四字,现在有八个像素的Alpha了!</font></p><p><font face="Tahoma" size="2">movq mm4,mm0 //Source-&gt;mm4</font></p><p><font face="Tahoma" size="2">movq mm5,mm1 //Overlay-&gt;mm5</font></p><p><font face="Tahoma" size="2">psubusw mm4,mm1 //Source-Overlay,饱和减,小于0为0</font></p><p><font face="Tahoma" size="2">psubusw mm5,mm0 //Overlay-Source,饱和减,小于0为0</font></p><p><font face="Tahoma" size="2">pmullw mm4,mm3 //Alpha * (Source-Overlay)</font></p><p><font face="Tahoma" size="2">pmullw mm5,mm3 //Alpha * (Overlay-Source)</font></p><p><font face="Tahoma" size="2">psrlw mm4,8 //除以256,now mm4 get the result,(Source-Overlay)&lt;0 部分</font></p><p><font face="Tahoma" size="2">psrlw mm5,8 //除以256,now mm5 get the result,(Overlay-Source)&gt;0 部分</font></p><p><font face="Tahoma" size="2">paddusw mm0,mm5 //饱和加到原图象:D=Alpha*(O-S)+S,(Source-Overlay)&lt;0 部分</font></p><p><font face="Tahoma" size="2">psubusw mm0,mm4 //饱和加到原图象D=S-Alpha*(S-O),(Overlay-Source)&gt;0 部分</font></p><p><font face="Tahoma" size="2">packuswb mm0,mm0 //紧缩到低32bit</font></p><p><font face="Tahoma" size="2">mov edx,dword ptr </font></p><p><font face="Tahoma" size="2">movd dword ptr ,mm0 //保存结果</font></p><p><font face="Tahoma" size="2">emms ///必要的!Empty MMX Status</font></p><p><font face="Tahoma" size="2">} 以上算法和常规算法比较:</font></p><p><font face="Tahoma" color="#ff9966" size="2">Legend PII 400 With damnble,extremely Slow Sis6326 Video Card: 640*480*32bit bitmap:</font></p><p><font face="Tahoma" color="#ff9966" size="2">Normal algorithm:170-180 ms</font></p><p><font face="Tahoma" color="#ff9966" size="2">This algorithm:Below 40 ms</font></p><p><font face="Tahoma" size="2">均包含拷贝内存时间,纯处理时间只要20ms, 就是说如果用DirectX,Blt,BltFast通常比memcpy快很多.就小于40ms了</font></p><p><font face="Tahoma" size="2">总结: 反复使用紧缩移位,紧缩扩展,紧缩压缩指令,并施加饱和运算等,是用MMX写算法的核心。</font></p><p><font face="Tahoma" size="2">程序员必须对数制,内存结构,定点数很熟悉才能写出高效率的MMX加速的子程序。</font></p>
页: [1]
查看完整版本: MMX版本的Alpha Blend算法实现