Bug 694528 - excessive memory usage on some platforms
Summary: excessive memory usage on some platforms
Status: NOTIFIED FIXED
Alias: None
Product: Ghostscript
Classification: Unclassified
Component: Graphics Library (show other bugs)
Version: 9.05
Hardware: PC All
: P2 normal
Assignee: Ray Johnston
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-08-18 22:03 UTC by Henry Stiles
Modified: 2014-01-15 16:24 UTC (History)
1 user (show)

See Also:
Customer: 460
Word Size: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Henry Stiles 2013-08-18 22:03:55 UTC
The customer reports:

debugbin/gs -Z: -dNOPAUSE -dSAFER -dBATCH -r600 -Ilib:Resource/Font -sDEVICE=tiffg4 -sOutputFile=BEAZH3P3.patch600.tiff ~/Downloads/BEAZH3P3.pdf

consumes much more memory on some hosts than others, in particular their AIX host is using 140 MB and a linux 32 bit system is using only 70 MB.  We have reproduced ~150 MB usage on 64 bit linux and 43 MB on windows (32 bit? )

The test file is attached to bug # 694514
Comment 1 Ray Johnston 2013-09-06 08:44:59 UTC
I did reproduce this on linux 64-bit build uses double what I see on Windows
32-bit build
Comment 2 Henry Stiles 2013-12-14 06:59:17 UTC
It took me quite some time to track this down, a good exercise after Maui ;-).  Anyway clamp_pattern_bbox() produces a much larger box on the 64 bit machine due to a very small floating point difference on 64 bit.  The bbox upper y for 64 bit is 0.000171661376953125 and 0 on 32, in proportion to the rest of the bounding box, this difference is very small.  The algorithm that calculates the clamped box increments the needed pattern box by several inches due to the slight imprecision.  So the clamp_pattern_bbox algorithm could be made more resilient to small floating point differences.  I suspect this would be difficult to do without breaking other things.  This difference in floating point values on 32 vs 64 can be traced back to the transform routine called from compute_inst_matrix() and gs_bbox_transform()


/* Transform a point. */
int
gs_point_transform(floatp x, floatp y, const gs_matrix * pmat,
		   gs_point * ppt)
{
    /*
     * The float casts are there to reproduce results in CET 10-01.ps
     * page 4.
     */
    ppt->x = (float)(x * pmat->xx) + pmat->tx;
    ppt->y = (float)(y * pmat->yy) + pmat->ty;

if the float casts are removed the results on 32 and 64 are consistent.

If they remain I get the following strange result on 64 bit:

given y = 800 and the pmat = {xx = 10, xy = 0, yx = 0, yy = -10, tx = 0, ty = 0.000171661377}

ppt->y = -8000! While the 32 bit and predicted result is ppt->y = -7999.9998...

The 32 and the predicted result yield a pattern bounding box that is a smaller and  for the page resulting in the lower memory usage.  So one reasonable attempt was to round the translation component of the pattern ctm and this does fix the problem for this file and the file only uses 78 MB (8 MB more the 32 bit not 140 MB) but it breaks other regression tests causing the bbox to be too small and thus we lose patterns on the page.  I experimented with some other obvious fixes and broke more regression files.  At that point I looked at the time I'd spent on this and thought it best to release my findings for review and possibly consider this a "LATER", the code as is produces correct results at the expense of more memory.

I do see enough hacking in the pattern clamping code to suggest we need a new approach rather than continuing to massage the floating point to suite the next incoming problem.
Comment 3 Robin Watts 2013-12-18 09:55:28 UTC
Fixed with:

commit 36f97ff44c7e94d1cf033a6495f2876b1976ca66
Author: Robin Watts <robin.watts@artifex.com>
Date:   Wed Dec 18 15:26:49 2013 +0000

    Bug 694258: Allow for floating point inaccuracies in pattern code.

    When calculating the regions 'touched' by pattern repeats, allow for
    inaccuracies in the floating point calculations.

A nicer fix might be to consider using fixedpoint here.