Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Speed optimisation in CodeGear RAD 2009 2

Status
Not open for further replies.

BoMi

Programmer
Jul 20, 2006
39
RS
Hi!
I also posted this question on the C++ Builder forum, but I would like to hear your opinion too. This forum has much larger user base, and it's the same IDE after all.
Here's the thing:


I've been using C++ Builder 2009 for the last couple of days trying to port one of my C++ Builder 2006 projects. The porting part went seamlessly. Had to change some parameter types for a couple of functions' calls due to the unicode support, but otherwise everything is great. I like this new RAD, everything works much faster than that 2006 version.

Now, to the problem. After porting the code is completely the same, except few function calls which needed parameters of type UnicodeString instead AnsiString (as before). But now, my application works much slower than when compiled with C++ Builder 2006.

Program essentially does some mathematics calculations during many iterations ('for' loop). Prevviously, before porting, the time taken for one iteration was in average 300-340 ms, but now, after porting, it takes at least 400 ms in average. This is a huge problem, especially if you take in consideration the number of iterations (which goes up to 30 000). Application is time critical and should run as fast as possible. Calculations involve mathematical operations with floating point numbers, simple additions, multiplications, divisions and a couple of square roots. Also includes a couple of 'if...; else if...; else...;' commands. Basically calculating some mathematical formula.

I changed project options to be the same as in the 2006 version (where they are the same, otherwise left default for release build), compiled for speed.

My question is: what is the possible reason (assuming the code is completely the same) and what might be a sollution? Is there a way to further optimise runtime performance through project options change?

I'm not looking for your suggestions for code optimisations, but for a reason the same code runs slower after compiled in C++ Builder 2009.


I'm open for your questions (for further explanations) and suggestions.

Thanks in advance.

Best regards...
 
My question is: what is the possible reason (assuming the code is completely the same) and what might be a sollution? Is there a way to further optimise runtime performance through project options change?

The first thought I had is that the generic library code in the new IDE might have been changed. They might be producing slower code. To check, if you have the C++ Builder 2006 library code, you can isolate the functions you call out of the libraries into your own unit and then run your program against that unit (compiled in 2009 ver of course) and see if it runs similarly.

The other possibility is that the compiler works your code differently in the 2009 version as opposed to the 2006 version. This is shown somewhat by your mentions of the Unicode changes (2 bytes per char instead of 1 for Ansi).

If your app is time critical and it takes 400 ms for one iteration (or even 300 as before), it would definitely pay to profile the code and then tune the code for a faster result.

Measurement is not management.
 
Thank you, Glenn9999, very much for your very quick response and for your input!

First of all, I should be more specific on that speed part. Actually 300 ms is quite good time, even excellent. What does matter is the running time of only one iteration, as it usually runs through only one. Only now and then we get a case when it has to run up to 30 000 times. So, time achieved before is something we here want now. Anything above would be unacceptable, and a raise of more than 50 ms is catastrophe. Especially in that many iterations case.

I've already thought about your first suggestion (that with new code in lybraries). But I postponed that 'cause I hoped I would get away with something quick as a solution but at the end I'll do what you proposed. The thing is that this application uses only basic mathematics functions, nothing special, and code that handles all that stuff was written completely in C, nothing Unicode there, heck I even don't use strings there.

Considering your second suggestion, well, I think you're probably right. But I have no idea how to make the compiler work the way it did on C++ Builder 2006. I set all options I thought are needed for optimisation for speed.
And those Unicode changes are just for SelectDirectory function and for TStringList which I use for streaming some text file from the resource file at the start of the application. That's all.
Besides, I measure time through various parts of code execution, and the result is that the passed time raise is in part of the code where the calculations take place, and there are no string operations at all.

Best regards...
 
I have a friend who writes video games. He told me once: Sqr root is very computationally heavy - optimize that code where possible. Convert as much as you can to integers - register math is much faster than floating point math - even if you have to multiply by several powers of 10 to take the decimals out of the equation.
 
But I have no idea how to make the compiler work the way it did on C++ Builder 2006. I set all options I thought are needed for optimisation for speed.

and the result is that the passed time raise is in part of the code where the calculations take place

If it is the second suggestion, all you can really do is tune the code. And that doesn't mean compiler options, it means going through and changing things so it will work faster (simpler algorithm, different methods, cleaner code, etc). The profiler program (that's what I meant by profile your code) should tell you to the specific statement where most of your time is occurring, and you should be able to act from there.

Measurement is not management.
 
Also, much depends on the algorithm in use, too. There can always be several tricks to do things in less time if you slow down and apply some math or logic. Like for (simple) example, using integer math instead of a Sqr function in a library (usually computationally heavy as well because they're made for any base or exponent value) when your input is an integer, or using bit shifts to multiply or divide by powers of 2. Or by pre-calculating things.

The key to faster code is always to find out where the main bottleneck is in the code and doing a decent amount of thought in getting it done.

Measurement is not management.
 
Thank you both guys!

Yes, Glenn9999, I already tried Sampling Profiler, and it, too, shows that the calculations are the most intensive part of the program.

But, I simply can't believe it's so different now. It should run the same or even faster than before.

You know, I ported another application from the same set. This one does array sorting using various algorithms. It now runs faster then before. Offcourse there's no calculations there, so is it maybe problem with math unit?

I'm going to implement sqrt through numerical methods or something, maybe even move completelly to integer arithmetic, but floats have never been a real problem before. I preferred them for easier implementation.
I guess then I should get back to my code (after years) and try to do some more optimisation. Code is implemented on some advanced algorithms (optimised) and there should be little to no room for more speed. Maybe fresh eyes help now.

Thank you for all your help Glenn9999, star for you.

Best regards...
 
I have new info on the problem.

I did some testing and what I came up with is: integer arithmetic is about 7 times slower in 2009 than in 2006 (at least on my computer). So, my thinking is that something is wrong with the code performing integer arithmetic, but I would definitelly like to know what you think? What may be the cause of this?

Do you guys know where in the source integer arithmetic is exactly located (like basic stuff: +, -, * and / operators)?

Best regards...
 
Do you guys know where in the source integer arithmetic is exactly located (like basic stuff: +, -, * and / operators)?

An integer op is any kind of basic arithmetic done on an integer. For example, 3 + 2 would generate an integer ADD, while 3.2 + 1.4 would generate a floating-point ADD.

One possibility that comes to mind (and I don't know because I don't have 2009 here to play with) is that there was a change in the 2009 version regarding the widths of integers. For example, if I were to define something as integer in Turbo Pascal or even Delphi 1.0, it would equate to a signed word (16-bit). Now in Delphi 2.0 onwards to Delphi 2006 (that I know of), integer equates to a signed double-word (32-bit).

Now it's possible that CodeGear/Embarcadero/whatever they call themselves now, sought to add 64-bit support, given the preponderance of newer processors which support it. Given that possibility, the compiler might be seeing integer as a signed quad-word (64-bits). Now, the compiler might be creating a kludge to run on regular 32-bit processors which follows what is done to support 64-bit numbers when you expressedly specify them (Int64). This is similar to what was done to support 32-bit integers on 16-bit platforms (2 integer ops, ADD; and ADD&CARRY).

How to test? You can try changing anywhere integer appears in the source to Int64 and compile it in the 2006 version to see if it gets slower. Or you can look for the expressed definition in 2009 (if there is one, remember all of this is just a guess), and change all integer to that.

In Delphi 2 to Delphi 2006, the expressed definition for a 16-bit integer is smallint[/b]. You can always see if there is an expressed definition of a 32-bit integer defined within the docs.

Hopefully you figure out the problem, where ever it is.

Measurement is not management.
 
Whoops, I forget a bit. There is an expressed 32-bit integer definition already: Longint. That would be what to try to change the definitions to if you went the 2009 route to see if the code gets faster.

Measurement is not management.
 
Hey, Glenn9999, thanks for still being around trying to help. I really appreciate it.

About those operators. Well, I don't know, never actually thought about it (until now, when I'm desperate and trying everything that comes to my mind), but there must be something to tell compiler that when you code a + b, it actually do the add operation. I thought there should be some assembly code or something that does the actual implementation of those operators. But, I'm no expert, so I'm talking nonsense probably (in that case, just ignore all of this).

I tried what you suggested (changing integer types) and nothing happens. Nothing noticeable at least. Plus/minus a few miliseconds and that's it. It's still so slow. It's amazing actually, floating point operations are now faster 2,5 - 3 times roughly than integer counterparts. :-D

About 64-bit support - I heard that they're going to add it in the next studio which should be on the market later this year.

Still nothing for me then. I will take a break on this and give it a try again now and then in my spare time. Maybe something all of a sudden clicks in the right place.

Thank you Glenn9999 for all your help and patience.

Best regards...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top