3

I want to improve the running time of some code.

In order to that I first time the running time of all relevant code, using code like this:

before:= rdtsc;
myobject.run;
after:= rdtsc;

Then I zoom in and time a relevant part, like so:

procedure myobject.part;
begin
  StartTime:= rdtsc;
  ...
  EndTime:= rdtsc;
  inc(TotalTime, (EndTime- StartTime));
end;

I have some code to copy paste the timings into Excel, a typical outcome would look like:

Timing difference should not be there
(the 89.8% and 10.2% adding up to 100% is a coincidence and has nothing to do with the data or the question)
(when the data shows 1 it means 0 to avoid divide by zero errors)

Note the difference between run A and run B.
I have not changed anything yet so run A and B should give the same running time.
Further note that I know that on both runs procedure part was invoked exactly the same number of times (the data is the same and the algorithm is deterministic).

The running time of procedure part is very short (it is just called many times).
If there was some way to block out other processes during these short bursts of runtime (less than 700 CPU cycles) my timings would be much more accurate.

How do I get these timings to be more reliable?
Is there a way to monopolize the CPU to only run my task when timing and nothing else?

Note that I'm not looking for obvious answers like:
- Close other running programs
- Disable the virusscanner etc...

I've tagged the question Delphi because I'm using Delphi right now (and there may be some Delphi specific option to achieve this result). I've also tagged it language-agnostic because there may be some more general way.

Update
Because I'm using the CPU instruction RDTSC I'm not affected by CPU throttling. If the CPU slows down, the number of cycles stays the same.

Update2
I have 2 answers, but neither answers the question...
The question is how do I prevent these changes in running time? Do I have to run the code 20x and always compare the lowest running time out of the 20 runs?
Or to I set my program priority to realtime?
Or is there some other trick to use so my code sample does not get interrupted?

Johan
  • 74,508
  • 24
  • 191
  • 319

2 Answers2

4

To want to improve the running time of some code.

In order to that I first time the running time of all relevant code, ...

OK, I'm a bit of a stuck record on this subject, but lots of people think that to improve running time requires first measuring it accurately.

Not So.

Improving running time requires finding out what's taking a large fraction of time (the exact fraction does not matter) and doing it differently or maybe not at all. What it's doing is often not revealed by timing individual routines.

Here's the method I use, and here's a very amateur video of it.

Community
  • 1
  • 1
Mike Dunlavey
  • 40,059
  • 14
  • 91
  • 135
  • 4
    +1 This is the single most productive profiling advice I have ever encountered. I used this very technique last week with great success. – David Heffernan Sep 24 '13 at 15:06
3

The problem with profiling your code like that, by sticking special statements into it, is that those special statements themselves take time to run. And since the things taking the most time are likely to be things happening in tight loops, the more they run, the more they distort your timings. What you need for good information is something that will observe your program from outside, without modifying the executing code.

In other words, you need a sampling profiler. And there just happens to be a very good one for Delphi available for free, by the rather descriptive name of Sampling Profiler. It runs your program and watches what it's doing, then correlates that against the map file (make sure to set up your project options to generate a Detailed map file) to give you an intelligible readout on what your program is spending its time on.

Enabling the map file

And if you want to narrow things down, you can use OutputDebugString to output profiling commands to make it only pay attention to specific parts of your code. It's got instructions in the help file.

I've used a lot of different methods, and this is the most useful way I've found to figure out what Delphi programs are spending their time on. And it's free. Give it a try.

Johan
  • 74,508
  • 24
  • 191
  • 319
Mason Wheeler
  • 82,511
  • 50
  • 270
  • 477
  • The special statement is the opcode `rdstc` + one write to memory. So that hardly takes any cycles. But I like the profiler to pinpoint the routine that's taking the most time. – Johan Sep 24 '13 at 15:28