高手请进:(附源码),256色旋转算法速度问题:角度越大,速度越慢.(原因是内存颠簸造成,)

jinvqing 2007-07-11 11:35:50
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;
...全文
219 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhuyanfeng 2008-08-06
  • 打赏
  • 举报
回复
楼主的这个程序速度肯定是很慢的,用GDI+可以快速实现,并且不有抗锯齿功能。我写过一个指针时钟就是用的GDI+,效果非常好。
http://topic.csdn.net/u/20070708/21/eea841ff-647f-47a1-9259-f072331c7b5f.html?seed=534823055
housisong 2007-07-15
  • 打赏
  • 举报
回复
我实现了 针对大图片的预读缓冲区优化的旋转
可以看我的blog文章《图形图像处理-之-任意角度的高质量的快速的图像旋转 下篇 补充话题》:http://blog.csdn.net/housisong/archive/2007/06/29/1671378.aspx
旋转速度和角度关系不太大了;
brightyang 2007-07-11
  • 打赏
  • 举报
回复
确实要高手才敢进~~~

看来又自大了一回
ERR0RC0DE 2007-07-11
  • 打赏
  • 举报
回复
不懂,LZ写个简单调用看看。
小笨象 2007-07-11
  • 打赏
  • 举报
回复
用GDI+吧。俺已经完美实现了。
jinvqing 2007-07-11
  • 打赏
  • 举报
回复
因为功力有限,还未实现过prefetchnta、prefetcht0指令.
我检查过,当此角度85度到90度时,带箭头的那条指令SrcTMP[dx+dy*BMPWidth]的内存地址一下子从一个$300000附近跳到$0附近.可能缓存的路数不够,使CPU命中Cache命中率偏低.
我也试过SrcTMP[random(BMPHeight*BMPWidth)]试速度,速度不快.
试过SrcTMP[dx+dy*BMPWidth div 2]试速度,速度还可以.

此程序是可实现完全的任何角度的旋转,但有折波线.
housisong 2007-07-11
  • 打赏
  • 举报
回复
旋转确实有这个问题
这个不叫“内存颠簸”吧 ,“内存颠簸”应该是因为缓存的路数不够,造成类似“hash”碰撞,从而降低缓存利用率;
这个应该是内存预取失效之类的,就是CPU预取的数据大部分是无效的(CPU会一次连续读取64字节到缓存,但某些角度的旋转需要的数据经常只有一个颜色数据(一般1-4字节),大部分数据都白读了);

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

(ps: 我没有尝试过这个方案;
我的blog中也写了几篇关于图像任意角度旋转的文章,并且还有带插值的高质量旋转实现)
hangzhou_hammer 2007-07-11
  • 打赏
  • 举报
回复
LZ 你的 程序能完全的任何角度的旋转????没有波折线?。我大学数学没学好,高中的三角函数来用,由于计算后坐标点的误差[小数部分不知道如何处理]~忽略或四舍五入都有波折出现。不晓得 photoshop 里的函数怎么处理的~

16,749

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧