By Stan Lackey
BASIC profiler speeds up your programs.
Track down those bottlenecks in your BASIC programs with Bottleneck Breaker. By tracking the amount of processing time each program line requires, this BASIC profiler helps you pinpoint the routines that need the most streamlining. BottleneckBreaker is a set of BASIC programs that work on all Atari 8-bit computers with at least 48K memory and a disk drive.
Programmers spend much time speeding up their programs. The most common streamlining methods include converting slow or heavily-used segments into machine language subroutines, using data tables in place of complicated functions, string equivalencing and a host of other techniques.
First, though, you have to find the bottlenecks--the slowest routines in your program. This can be difficult in a large program with many GOSUBs and GOTOs. Bottleneck Breaker finds these bottlenecks by identifying the program lines that use the most processing time. Such a "profiling" system lets you measure and record the performance of each section of your program.
Bottleneck Breaker consists of three programs that work together to analyze your BASIC program as it is running. Seconds after your program is done, the profiler's report is ready to be displayed or printed. With this report in hand, tracking down BASIC bottlenecks is as easy as reading a scorecard.
Type in Listing 1, PROFILE1.BAS, check it with TYPO II and SAVE a copy to disk.
Next, type NEW then type in Listing 2, PROFILE2.LST, check it with TYPO II and LIST a copy to disk.
Now, type NEW, then type in Listing 3, PROFILE3.BAS, check it with TYPO II and SAVE a copy to disk.
Finally, type NEW, then type in Listing 4, PROFTEST.BAS, checking it with TYPO II, and SAVE a copy to disk. PROFTEST.BAS is a short BASIC program we'll use to test the profiler. It performs a variety of functions within a time-consuming loop, and is a good program to start with.
Listing 5, PROFILE.MG5, is the MAC/65 assembly language source code for the profiler. You do not need to type it in to use the programs.
Antic Disk owners will find all of these listings on the monthly disk.
YOUR FIRST TIME
Bottleneck Breaker is easy to use. Each program's final screen tells you what to type next. Before using the profiler on your own program, though, you should first try it on the short example program, PROFTEST.BAS. Put a disk containing your profiler programs into the drive and type:
This program loads the profiler's machine language routine and sets up the POKEY timer interrupt.
Next, LOAD the program to be profiled. For this test case, type:
After making sure your program has no lines numbered 1-3 or 31000- 31010, type:
This file adds the necessary commands to start and stop the profiler. Finally, type RUN. It takes about a minute to clear the counters. Then your BASIC program will begin.
As your BASIC program runs, the profiler monitors it and updates its counters, which are kept in a separate 8K block of protected memory.
When your program stops, you should see the message: DONE...
Next: RUN "D:PROFILE3.BAS"
If you don't see this message, you must type GOTO 31000 at the READY prompt. Otherwise, the profiler will not stop profiling!
Now it is time for the profiler to fetch, analyze and display your results. If your printer is on, you'll automatically get a hard copy of your report.
Type: RUN "D:PROFILE3.BAS"
This can take some time to RUN, as the data sets can be large. As it runs it reports on its status. When done, it reports on its status. When done, it should print a report similar to the following:
TOTAL COUNTS = 3389
LINE COUNTS PERCENT CUM PCT 120 2423 71.47 71.47 110 370 10.91 82.38 140 191 5.63 88.01 160 124 3.66 91.67
INTERPRETING THE REPORT
The report is sorted by execution speed, with the slowest program lines at the top.
The COUNTS column contains the raw data from the profiler's counters. The PERCENT column tells you what percentage of the processor's time was devoted to this line. The CUMPCT(Cumulative Percentage) column merely keeps a running total of the PERCENT column.
According to this report, line 120 has the biggest bottleneck. This line uses most of the computer's processing time--more than 71 percent of it! If you refer to PROFTEST.BAS, you'll see that line 120 contains a cosine function, which takes quite long time to execute.
Line 110 is the next largest bottleneck. This line contains a division operation, which also takes a long time, but only about one-seventh the time of the cosine function, according to the profile.
Checking the CUM PCT column, see that the four highest lines in the profile consume over 91% of the total processing time.
Note that the profiler uses a statistical method, and will probably never produce exactly the same results twice.
A perfect profiling system would not take processing time away from your program, would not need any memory space, and would show how much time was spent executing each program line.
The ideal profiling system would also have a counter for each line in your BASIC program. These counters would keep a record of the number of times each line had been executed.
Finally, the profile would use all of this information to calculate an average of the actual time spent executing each statement.
While Bottleneck Breaker is not a perfect system, it is accurate and reliable enough to measure almost every type of BASIC program.
Since Bottleneck Breaker runs concurrently with the program being profiled, each must have its own share of processing time and RAM. Bottleneck Breaker needs about a 25 percent share of processing time. This means that your programs will RUN about 25 percent slower while they are being profiled.
The profiler also needs 8K of RAM for its counters. If you need to profile a large program that needs this 8K block of memory, you should break it into groups of stand-alone subroutines, LIST each group to disk, then individually profile each group.
Finally, Bottleneck Breaker does not have a counter for each line in your BASIC program. Instead, the profiler has one counter for each range of 10 line numbers. For example, any lines numbered 10-19 would all share counter #11, all lines within the range 20-29 would use #2, and so on.
If you number your program in tens (10, 20, 30...), as most BASIC programmers do, you'll have one counter for each line. If your program is not numbered in tens-and you want to assign one counter per line-- you must renumber your program (NOTE: Some BASIC programs won't work if renumbered. Be sure to make a backup of your program before renumbering, just in case.)
HOW IT WORKS
Bottleneck Breaker is a collection of three BASIC programs that all work together. The first program, PROFILE1.BAS, POKEs the profiler's machine language (ML) counting and timing routine into memory, just above the counters.
The second program, PROFILE2.LST, is really just five lines of BASIC which are merged into the program to be profiled. These lines control the profiler's ML routine, clear the counters and set the timers.
The third program, PROFILE3.BAS, analyzes the 8K block of counters and displays the results of the profile.
The profiler stores its data in an 8K block of 16-bit counters. That's enough RAM for 4,096 counters. Since BASIC's maximum allowable line number is 32767 and up to ten lines may share a counter, we'll only need 3,276 counters, or a little more than 6K. The profiler's ML routine sits in the remaining 2K of this block.
The brains of the system is the profiler's ML routine, called "SAMPLER." It is entered on the POKEY Timer One interrupt. SAMPLER is controlled through memory location 40704 ($9F00), which is used as a flag to start and stop profiling. SAMPLER checks this location whenever it receives the Timer One interrupt, and only proceeds if the value is not zero.
SAMPLER examines your BASIC program more than 250 times per second. During each pass it checks STMCUR (memory locations 138-139, $8A-$8B) to determine which line is being executed, then increments the appropriate counter.
After incrementing the counter, the routine checks for any overflows (the high bit will be a 1). When this happens, typically only after a very long run, SAMPLER is disabled. No further samples are taken, to avoid losing accuracy in the results.
Note that the SAMPLER routine uses memory locations 203-208 ($CB-$D0). If your program uses these locations, the profiler may produce wrong answers or crash.
You should also be sure that the program being profiled does not use lines 1-3 or 31000-31010. Otherwise, you won't be able to add the program lines which control the Profiler.
Finally, if the profiler tries to sample your program while the BASIC interpreter is moving from one line to the next, a garbage line number will appear in the final report. This happens rarely enough that it does not affect the results in any significant way.
As written, Bottleneck Breaker requires 8K of RAM for its counters. Antic challenges you to relocate the profiler's counters to the 130XE's alternate memory bank, allowing the profiler to work with larger programs.
The best modification, in the opinion of the Antic staff, will receive the winner's choice of any single Antic Software product from the Arcade Catalog. Entries must be received before May 15, 1989. These become the property and will not be returned. Send your entries to: Bottleneck Contest, Antic Magazine, 544 Second Street, San Francisco, CA 94107.
Stan Lackey is a computer hardware engineer at BBN Advanced Computers Inc. in Cambridge Mass. and a member of the Acton-Boxboro Atari Computer User Society (ABACUS.) This is his first appearance in Antic.