读书人

:(附源码),256色旋转算法速度有关问题

发布时间: 2012-02-13 17:20:26 作者: rapoo

高手请进:(附源码),256色旋转算法速度问题:角度越大,速度越慢.(原因是内存颠簸造成,)
procedure Rotate(Bmp:Pointer;BMPWidth,BMPHeight,cx,cy:Integer;Dst:Pointer;DstWidth,DSTHeight:integer;Angle:Double);
var
x,y,
dx,dy,
sdx,sdy,
xDiff,yDiff,
isinTheta,
icosTheta: Integer;
SrcTmp:PByteArray;
DstTmp: PByte;
sinTheta,
cosTheta,
Theta: Double;
x_1,y_1:Integer;
calcfirstx,calcfirsty:Double;
begin
Theta:=-Angle*Pi/180;
sinTheta:=Sin(Theta);
cosTheta:=Cos(Theta);
xDiff:=(DstWidth-BmpWidth)div 2;
yDiff:=(DstHeight-BmpHeight)div 2;
isinTheta:=Round(sinTheta*$10000);
icosTheta:=Round(cosTheta*$10000);
DstTmp:=PByte(DST);
SrcTmp:=PByteArray(BMP);
x_1:=DstWidth-1;
y_1:=DstHeight-1;
calcfirstx:=cx-cx*cosTheta+cy*sinTheta-xDiff;
calcfirsty:=cy-cx*sinTheta-cy*cosTheta-yDiff;
for y:=y_1-100 downto 0 do
begin
sdx:=Round((calcfirstx-y*sinTheta)*$10000);
sdy:=Round((calcfirsty+y*cosTheta)*$10000);
for x:=x_1 downto 0 do
begin
dx:=sdx shr 16;
dy:=sdy shr 16;
if(dy <BMPHeight)and(dx <BMPWidth) then
begin
DstTmp^:=SrcTMP[dx+dy*BMPWidth];// < <--------------此处角度大时内存颠簸严重(图像大小:2048*1536)
end;
inc(sdx,icosTheta);
inc(sdy,isinTheta);
Inc(DstTmp);
end;
end;
end;


[解决办法]
旋转确实有这个问题
这个不叫“内存颠簸”吧 ,“内存颠簸”应该是因为缓存的路数不够,造成类似“hash”碰撞,从而降低缓存利用率;
这个应该是内存预取失效之类的,就是CPU预取的数据大部分是无效的(CPU会一次连续读取64字节到缓存,但某些角度的旋转需要的数据经常只有一个颜色数据(一般1-4字节),大部分数据都白读了);

尝试一下自己手工预取试试 (在几百个CPU周期之前读一下那个内存数据;可以考虑专门的预取指令比如prefetchnta、prefetcht0等) ,然后让预读代码和实际处理代码交错起来

(ps: 我没有尝试过这个方案;
我的blog中也写了几篇关于图像任意角度旋转的文章,并且还有带插值的高质量旋转实现)
[解决办法]
用GDI+吧。俺已经完美实现了。

读书人网 >.NET

热点推荐