[Haskell-cafe] 2 optimization bugs ?

George Colpitts george.colpitts at gmail.com
Tue Jul 2 11:34:27 UTC 2024


It seems like I have found two optimization bugs. Before filing bugs , I
wanted to double check if others agreed and can reproduce the bugs.

Compile and run the attached file:

ghc -O2 optBugs.hs
Loaded package environment from
/Users/avie/.ghc/aarch64-darwin-9.10.1/environments/default
[1 of 2] Compiling Main             ( optBugs.hs, optBugs.o )
optBugs.hs:45:49: warning: [GHC-18042] [-Wtype-defaults]
    • Defaulting the type variable ‘b0’ to type ‘Integer’ in the following
constraints
        (Integral b0) arising from a use of ‘^’ at optBugs.hs:45:49
        (Num b0) arising from the literal ‘6’ at optBugs.hs:45:50
    • In the first argument of ‘counts’, namely ‘(10 ^ 6)’
      In the second argument of ‘(.)’, namely ‘counts (10 ^ 6)’
      In the second argument of ‘(.)’, namely ‘elems . counts (10 ^ 6)’
   |
45 | solve = product . map (+ 1) . elems . counts (10^6) --  1000000
   |
      ^

[2 of 2] Linking optBugs
avie at Anabela-Air Documents % ./optBugs +RTS -s
./optBugs +RTS -s
39001250856960000
   2,932,564,768 bytes allocated in the heap
     143,405,696 bytes copied during GC
      76,022,072 bytes maximum residency (4 sample(s))
      11,034,312 bytes maximum slop
             164 MiB total memory in use (0 MiB lost due to fragmentation)


                                     Tot time (elapsed)  Avg pause  Max
pause
  Gen  0       263 colls,     0 par    0.032s   0.036s     0.0001s
 0.0020s
  Gen  1         4 colls,     0 par    0.048s   0.060s     0.0150s
 0.0368s


  INIT    time    0.003s  (  0.003s elapsed)
  MUT     time    3.343s  (  3.333s elapsed)
  GC      time    0.080s  (  0.096s elapsed)
  EXIT    time    0.002s  (  0.008s elapsed)
  Total   time    3.428s  (  3.440s elapsed)


  %GC     time       0.0%  (0.0% elapsed)


  Alloc rate    877,099,801 bytes per MUT second


  Productivity  97.5% of total user, 96.9% of total elapsed


Now change the line

    solve = product . map (+ 1) . elems . counts (10^6) --  1000000

to

    solve = product . map (+ 1) . elems . counts 1000000

save the file to disk, compile and rerun:

ghc -O2 optBugs.hs
Loaded package environment from
/Users/avie/.ghc/aarch64-darwin-9.10.1/environments/default
[1 of 2] Compiling Main             ( optBugs.hs, optBugs.o ) [Source file
changed]
[2 of 2] Linking optBugs [Objects changed]
avie at Anabela-Air Documents % ./optBugs +RTS -s
./optBugs +RTS -s
39001250856960000
   1,920,053,000 bytes allocated in the heap
          16,488 bytes copied during GC
       8,028,224 bytes maximum residency (2 sample(s))
         393,152 bytes maximum slop
              22 MiB total memory in use (0 MiB lost due to fragmentation)


                                     Tot time (elapsed)  Avg pause  Max
pause
  Gen  0       239 colls,     0 par    0.000s   0.001s     0.0000s
 0.0002s
  Gen  1         2 colls,     0 par    0.000s   0.001s     0.0007s
 0.0011s


  INIT    time    0.003s  (  0.003s elapsed)
  MUT     time    2.011s  (  2.015s elapsed)
  GC      time    0.001s  (  0.002s elapsed)
  EXIT    time    0.000s  (  0.007s elapsed)
  Total   time    2.015s  (  2.027s elapsed)


  %GC     time       0.0%  (0.0% elapsed)


  Alloc rate    954,738,679 bytes per MUT second


  Productivity  99.8% of total user, 99.4% of total elapsed


Allocation decreased by a billion bytes and runtime has decreased by almost
a third. This is hard to believe. The obvious explanation is that I dropped
a zero when I wrote out 10^6 but I checked that I have six zeros. Also I
get the same answer in both cases.

Next uncomment the following two lines in factor:

      -- let p = sm ! m

    -- sm = smallest maxN

and comment out the line:

   let p = smallest maxN ! m

save the file, compile and rerun:


ghc -O2 optBugs.hs
Loaded package environment from
/Users/avie/.ghc/aarch64-darwin-9.10.1/environments/default
[1 of 2] Compiling Main             ( optBugs.hs, optBugs.o ) [Source file
changed]
[2 of 2] Linking optBugs [Objects changed]
avie at Anabela-Air Documents % ./optBugs +RTS -s
./optBugs +RTS -s
39001250856960000
      16,051,152 bytes allocated in the heap
          10,040 bytes copied during GC
          44,328 bytes maximum residency (1 sample(s))
          29,400 bytes maximum slop
              22 MiB total memory in use (0 MiB lost due to fragmentation)


                                     Tot time (elapsed)  Avg pause  Max
pause
  Gen  0         2 colls,     0 par    0.000s   0.000s     0.0001s
 0.0002s
  Gen  1         1 colls,     0 par    0.000s   0.001s     0.0015s
 0.0015s

  INIT    time    0.003s  (  0.003s elapsed)
  MUT     time    0.019s  (  0.018s elapsed)
  GC      time    0.000s  (  0.002s elapsed)
  EXIT    time    0.001s  (  0.002s elapsed)
  Total   time    0.023s  (  0.025s elapsed)

  %GC     time       0.0%  (0.0% elapsed)

  Alloc rate    866,786,478 bytes per MUT second

  Productivity  78.9% of total user, 72.5% of total elapsed

Allocation has dropped from 2 billion bytes to 16 million and runtime has
dropped from 2 seconds to 0.02 seconds. I think the optimizer should move
the call to smallest outside of the "loop" in go. This seems like a bug to
me.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20240702/b0cce34d/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: optBug.hs
Type: application/octet-stream
Size: 1296 bytes
Desc: not available
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20240702/b0cce34d/attachment.obj>


More information about the Haskell-Cafe mailing list