开发者

Increasing performance of timer event in delphi

I am creating an app which mainly relies on timer,

when the timer ticks my app will do a huge task;(my task manager says 50%, in a dual core machine,one core is fully used) . It is creating two objects and 17 variables on an event.

How can i improve the performance of my timer event开发者_如何学运维 ;below are my ideas ,please clarify me whether it will improve or make worse

  1. creating and initializing local variables globally(declare them globally)
  2. concurrency // is it possible to do in delphi
  3. using a loop with sleep function instead of timer

and i need more idas from you to decrease the timer inteval as low as possible and keep the cpu usage as low as possible

The main reason for sluggishness is nested 4 loops ; but i have no any why to remove or reduce them

//======================== updated =================================================

Thanks for the response my app will monitor webcam and alert when a motion is detected ; but sorry i cant post my code here;but i can tell u what is happening around the code

first the image will be broken in to 25*25 pieces ;2 loops for this

average color of a piece is stored retrived and compared with the current one ; 2 loops for this

then the app will show where the motion is detected

timer interval is currently set to 300


Creating 2 class instances and 17 variables will just be done in no time - in much less time than the timer resolution is, in all cases.

So there something else in your timer which burns your CPU. Data access, processing, calculation. It is impossible to guess what does need optimization without more information and source code.

What you'll need is to profile your application. You have AQTime in the latest versions of Delphi, but you may take a look at GPProfile or ProDelphi. You can use a profile-ready logging system like ours to make it on customer-side, if needed. Then you'll see what is slow, i.e. where most of the time is spent.

Using a loop with a sleep (in a background thread I guess) won't be faster than a timer.

IMHO what makes some repetitive task fast is using some pre-computed tables. There are perhaps some data that do not need to be computed or retrieved each time. So you may store those data in shared variables, and use it in the event handler. Always consider that changing an algorithm or avoiding data/hardware access is the key of speed. And always trust a profiler, not your first instinct.

After updated question

So your problem is directly related to process time of a picture. You still are in need of actual profiling to guess what shall be improved. I guess that you retrieve the picture in this timer. The process of a webcam picture won't take 300 ms. So a possibility may be to use a background thread to retrieve the webcam images, push them in a round-robin list, then let the timer only process the latest image when asked for. But a real profiling of your code is needed.

If the picture process itself in Delphi loops is the slow part, a sampling profiler will help you see which line of code needs speed up. Some advices in this case:

  • Try to use local variables within each loop to avoid re-computing of indexes (using pointers) or values (store them in the stack) in nested loops;
  • Try to access memory not randomly, but block per block (for better cache performance);
  • Align your data on 4 or 8 bytes alignment;
  • Unroll the inner loops (this may be a major speep up on modern CPUs) - e.g. if you merge some pixels blocks, hardwire the block reading and computing in your code, instead of using a for x := xRef-3 to xRef+3 do.. - main rule is to avoid any branch in your code - the less if ... then or for ... to appear in your code, the better;
  • Consider adding asm SSE/SSE2 instructions instead of pascal code (difficult part but also the more powerful), or use a third-party optimized library for your processing - there are several motion detection libraries around.


  • creating and initializing local variables globally(declare them globally): probably will not help, but clutter your code. Local variable access is not that expensive.

  • concurrency // is it possible to do in delphi: Possible, but doing things wrong in a separate thread will eat CPU time just as doing things wrong in the timer event. What's worse, you possibly would create the thread more than once if the timer re-triggers before the thread created on the previous timer tick has finished its job

  • using a loop with sleep function instead of timer: Will probably yield the same result, and also block the UI, making your app less responsive

If you post the code and timer settings, and the requirements for the timer (which lead to your specific timer settings) I'll update the answer to make it more constructive.

** Update/Addition **

Not seeing ANY code I can only estimate that you probably have a lot of Windows API calls in it. You could monitor which calls are made with what values, identify those that are called over and over with the same set of parameter values, and cache, or completely take out of the loop, the result calculation. (That's similar to the precalc suggestion in the other answer.). For image manipulation, color mapping computing (palette, native->RGB conversion, etc.) are frequent operations that can easily be optimized by replacing API calls with pre-calculated lookup tables.

If you do most calculations/image data manipulation yourself, you either must optimize your code yourself, among others by using the suggestions from the "profile it!" answer, OR, which I'd suggest, post some code.

Nobody can diagnose a defective machine that only a brief description is given of. Without even a recording of the operating sound, or a picture of specific engine details, all the mechanic can say is "true, there is a problem, but more I cannot say" if you just tell him "it does not run at expected speed".


Move your processing into a separate worker threads. Have one thread reading the images off of the webcam and pushing them into a queue somewhere for processing. Have another thread (or pool of threads) process the queue. When finished, post the final results to the main thread for display.


There is no such thing as boosting the "performance" of a timer. A timer does its thing, pretty well, and that's that.

There is only one conclusion to draw: your code takes more then 300 milliseconds to perform. Profile and refactor optimize your code, or set the timer interval to a greater value.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜