Monday, February 21, 2005

The FNO Hack

Background
Like the previous hack, this took place on a Honeywell 6000 computer running GCOS. We had an application that used a random access file for persistence in a high traffic environment (~50 allocations/second for sustained periods of time.)

To understand the hack you need to understand how floating point math was implemented on the Honeywell 6000 machine.

The H6000 worked with floating point numbers in the EAQ register where E is an eight bit exponent register and AQ is a double-word (72 bit) general purpose register used as a mantissa in this case. Floating point operations did not always produce normalized results, so a special instruction, FNO, normalized the current contents of the EAQ register.

Floating point normalization
Consider Avogadro's number = 6.022 × 10**23. Another way to express this is 0.602 x 10**24. The first version is normalized (base 10). The second is not. Notice the loss of precision. Binary normalization works the same way. To normalize a number you shift it left to get rid of leading zeroes and adjust the exponent appropriately.

The problem
The challenge was to control the allocation of blocks in the random file. Remember memory is tight, so a free list is not a good solution. Instead we used an allocation table with each bit corresponding to a block in the file.

How can you find an available block as fast as possible.

The hacker Bob ("If you need comments to understand my code, you shouldn't be reading it!") Miller

The hack
An important decision was to represent available blocks as one bits and used blocks as zero bits. This allowed testing 72 bits at a time when looking for an available block by loading the AQ register and branching if the result was non-zero. Thus the the algorithm was:

loop:
load AQ tablepointer (auto incremented by 2 words)
jump if zero to loop
and now the hack:
load the E register with zero
FNO (floating point normalize)
copy the E register to a general purpose register.
Add 36 * the word offset in the allocation table

to get the available block number.




Rate this hack from 0 (slimey) to 10 (righteous).



Important factors in my rating of this hack are:

Although it uses an instruction for "the wrong purpose" if you read the description of the instruction in terms of how it maniuplates bits it does all the right things. In other words as long as Honewell doesn't decide to change how they represent floating point the hack should continue to work.

This is a high use function that has a direct and visible impact on performance.

Rating
I give it a 9 out of ten (If Bob had believed in comments it might actually be a 10).

No comments: