减少VCL花费的CPU时间 [英] Reduce CPU time spent in VCL

查看:201
本文介绍了减少VCL花费的CPU时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个MIDI播放器播放的音符为precisely尽可能是很重要的。我从来没有完全成功在于,总是指责定时器(见previous螺纹:的如何prevent提示中断定时器)。最近我获得了ProDelphi,开始测量究竟消耗了多少时间。其结果是相当惊人的,见下面的例子code。

It is important for a MIDI player to playback the notes as precisely as possible. I never quite succeeded in that, always blaming the timer (see a previous thread: How to prevent hints interrupting a timer). Recently I acquired ProDelphi and started measuring what exactly consumed that much time. The result was quite surprising, see the example code below.

procedure TClip_View.doMove (Sender: TObject; note, time, dure, max_time: Int32);
var x: Int32;
begin
{$IFDEF PROFILE}Profint.ProfStop; Try; Profint.ProfEnter(@self,1572 or $58B20000); {$ENDIF}
   Image.Picture.Bitmap.Canvas.Pen.Mode := pmNot;
   Image.Picture.Bitmap.Canvas.MoveTo (FPPos, 0);
   Image.Picture.Bitmap.Canvas.LineTo (FPPos, Image.Height);
   x := time * GPF.PpM div MIDI_Resolution;
   Image.Picture.Bitmap.Canvas.Pen.Mode := pmNot;
   Image.Picture.Bitmap.Canvas.MoveTo (x, 0);
   Image.Picture.Bitmap.Canvas.LineTo (x, Image.Height);
   FPPos := x;
//   Bevel.Left := time * GPF.PpM div MIDI_Resolution;
{$IFDEF PROFILE}finally; Profint.ProfExit(1572); end;{$ENDIF}
end; // doMove //

的测量(不含在Intel i7-920调试code,2,7Ghz):

The measurements are (without debug code on an Intel i7-920, 2,7Ghz):


    如图所示
  1. 95微秒为code

  2. 当一切除了现在注释掉的语句注释掉5.609毫秒( Bevel.Left:=

  3. 0.056毫秒,当所有code是由替换X:=时间* GPF.PpM格MIDI_Resolution;

  1. 95 microseconds for the code as shown
  2. 5.609 milliseconds when all is commented out except for the now commented out statement (Bevel.Left :=)
  3. 0.056 microseconds when all code is replaced by x := time * GPF.PpM div MIDI_Resolution;

只是围绕一个锥搬家费用60倍,CPU只是作为一个绘图画布。这让我感到惊讶。测量1的结果非常发声(还有比这只是更会),但2和3未。我需要某种形式的反馈给用户什么的球员现在正在处理,一些线路在钢琴卷是接受的方式。在我的上房减少了定时事件循环的C​​PU周期的追求,我有一些问题:

Just moving around a Bevel costs 60 times as much CPU as just drawing on a Canvas. That surprised me. The results of measurement 1 are very audible (there is more going on than just this), but 2 and 3 not. I need some form of feedback to the user as what the player now is processing, some sort of line over a piano roll is the accepted way. In my never ending quest of reducing CPU cycles in the timed-event loop I have some questions:


  • 为什么围绕一个斜角的成本是多少时间?

  • 有降低比上一个位图吸引更多的CPU周期的方式?

  • 有图纸时减少闪烁的方式?

推荐答案

您将无法改变世界,也不VCL也不支持Windows。我怀疑你是问得多那些...

You won't be able to change the world, nor VCL nor Windows. I suspect you are asking to much to those...

恕我直言,你最好改变一点点你的架构:

IMHO you should better change a little bit your architecture:


  • 声音处理应在一个(或多个)分隔线程(s)和不应该在所有链接到UI(例如不脱离其发送GDI消息);

  • UI刷新应使用定时器与一个500毫秒的分辨率(半秒刷新听起来有足够的反应),而不是每次有变化。进行

也就是说,编曲不会刷新的用户界面,但用户界面将定期向音序器是什么其当前状态。这将是恕我直言更加顺畅。

That is, the sequencer won't refresh the UI, but the UI will ask periodically the sequencer what is its current status. This will be IMHO much smoother.

要回答你的问题的确切:

To answer your exact questions:


  • 移动锥实际上是发送一些GDI消息,并且渲染将通过使用临时位图GDI堆栈(GDI32.DLL)进行;

  • 尝试使用更小的位图,或者尝试使用Direct X的缓冲区映射;

  • 尝试 DoubleBuffered:= TRUE 您TForm.OnCreate事件,或者使用专用的组件( TPaintBox )与整个成分含量的全球位图,用类似的东西为消息 WM_ERASEBKGND

  • "Moving a bevel" is in fact sending several GDI messages, and the rendering will be made by the GDI stack (gdi32.dll) using a temporary bitmap;
  • Try to use a smaller bitmap, or try using a Direct X buffer mapping;
  • Try DoubleBuffered := true on your TForm.OnCreate event, or use a dedicated component (TPaintBox) with a global bitmap for the whole component content, with something like that for the message WM_ERASEBKGND.

有些code:

   procedure TMyPaintBox.WMEraseBkgnd(var Message: TWmEraseBkgnd);
   begin
     Message.Result := 1; // no erasing is necessary after this method call
   end;

这篇关于减少VCL花费的CPU时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆