[Info-vax] Currency Math, Code Archeology, and Retrofitting (was: Re: New VSI Roadmap (yipee!))
Stephen Hoffman
seaohveh at hoffmanlabs.invalid
Tue Mar 3 10:49:00 EST 2015
On 2015-03-03 15:01:29 +0000, David Froble said:
> johnson.eric at gmail.com wrote:
>> On Monday, March 2, 2015 at 9:30:19 PM UTC-5, David Froble wrote:
>>
>>> Perhaps note the difference in CPU time between calling the subroutine,
>>> and executing almost the same exact code inline.
>>>
>>> Now, I'm assuming that a build in language function would be similar to
>>> inline code. Perhaps that is my mistake.
>>
>> The difference is striking. I wonder where the expense comes from.
>
> Subroutine frame set-up and break-down. Stuff needed for error
> trapping I believe. At least that was the discussion years ago.
On most architectures, subroutine calls and branches have an added
cost. The deeper the instruction pipeline, the more expensive these
get, as many users of older Intel x86 boxes learned with the Intel
Pentium 4 "NetBurst" boxes. This is part of the reason why threads
exist; threading is a way for the processor to quickly go do something
else while it's waiting for the data from cache or from main memory.
In at least some of the VMS programming languages, built-in functions
are generated as in-line code by the compiler. In many of the VMS
languages, functions are implemented as subroutine calls to a
language-specific shareable image or to the OpenVMS OTS or other
shareable image. Most code optimizers will try to unroll loops and
particularly when tuning for performance is requested, and will also
try to move functions inline to avoid stalls, and some will choose to
replicate executable code in the binary for better performance. What
BASIC and what GEM does in these cases, I don't particularly recall.
I would not expect particularly great performance from most of the
Itanium back-ends, but am certainly willing to be surprised — Itanium
is very different than many other platforms, which means that different
techniques were often needed for optimization; some of the common
compiler code generator optimization techniques weren't necessarily
applicable to VLIW. Investing in a compiler back-end is also a
longer-term effort and longer-term investment, and even the best and
most actively-developed compilers don't traditionally see particularly
substantial improvements in the performance of the generated code.
Floating point math itself can have a cost, as compared with integer
operations. Sometimes FP can be fast or faster, sometimes not. On the
older gear, the FP code I looked at was usually slower than the
integer, though that could be dependent on the presence of an
accelerator, or other such details. (This whole area wasn't
necessarily clear-cut on VMS or other platforms, either: some integer
operations used the optional DEC FP accelerator for performance
reasons.) See the SPEC CPU (SpecFP and SpecInt) data for details on
various platforms.
Having dealt with RSX-11M/M+ and TKB and BASIC+2 and the comparative
joys of moving to a flat virtual address space and DEC BASIC and boxes
with longer integers, I'd still likely migrate FP currency code over to
integer, either native or potentially over to extended-precision.
Extended-precision is less common with native 64-bit math on Alpha and
Itanium, but still necessary for some cases, and for when you're
dealing with governments and the 1%. In the past (having migrated BP2
and TKB-based code on RSX-11M/M+ over to DEC BASIC on VAX/VMS), I've
gone as far as using string math for some of the currency calculations,
and which was surprisingly performance-competitive with the FP code it
was replacing back, probably due to the BASIC application being
throttled by something other than that particular math. Would probably
use extended-precision there now, but the string math library was
available and debugged.
As anybody that's looked at or has done this integer migration, this is
somewhere between a hassle and a major hassle in any code base. As
for the priority of the migration, if the FP-based math is currently
all working out and there aren't pennies being flung around in the
accounting department in frustration, then this particular transition
wouldn't be a priority — I'd look to combine this transition with other
retrenchments in the existing code-base, such as adding support for
multiple currencies or potentially for operations with larger currency
values, or fixing other issues of data type mismatches or available
data ranges, or of the migration of storage of longword or quadword
local time over to UTC. Might also get rid of bitmasks or other older
and comparatively slower techniques, while I'm here, too.
Maintaining old code usually involves having an installed base, and —
as I've mentioned once or twice before — an installed base can be an
excellent impediment to making substantive changes, leading to more
than a little old and ugly code, and to various good-enough compromises
in the source code.
For those that are interested in this general area, there are more than
a few discussions of currency math around the 'net, and the various
folks that have run afoul of the details of how floating point actually
works.
<http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html>
<http://www.ima.umn.edu/~arnold/disasters/patriot.html>
<http://blog.plataformatec.com.br/2014/09/floating-point-and-currency/>
etc.
--
Pure Personal Opinion | HoffmanLabs LLC
More information about the Info-vax
mailing list