READE.md: Move `cabal install` instructions
[nofib.git] / README.md
1 # NoFib: Haskell Benchmark Suite
2
3 This is the root directory of the "NoFib Haskell benchmark suite". It
4 should be part of a GHC source tree, that is the 'nofib' directory
5 should be at the same level in the tree as 'compiler' and 'libraries'.
6 This makes sure that NoFib picks up the stage 2 compiler from the
7 surrounding GHC source tree.
8
9 You can also clone this repository in isolation, in which case it will
10 pick `$(which ghc)` or whatever the `HC` environment variable is set to.
11
12 Additional information can also be found on
13 [NoFib's wiki page](https://ghc.haskell.org/trac/ghc/wiki/Building/RunningNoFib).
14
15 ## Package Depedencies
16
17 Please make sure you have the following packages installed for your
18 system GHC:
19  * html
20  * regex-compat (will install: mtl, regex-base, regex-posix)
21
22 ## Using
23
24 <details>
25   <summary>Git symlink support for Windows machines</summary>
26   
27   NoFib uses a few symlinks here and there to share code between benchmarks.
28   Git for Windows has symlinks support for some time now, but
29   [it may not be enabled by default](https://stackoverflow.com/a/42137273/388010).
30   You will notice strange `make boot` failures if it's not enabled for you.
31   
32   Make sure you follow the instructions in the link to enable symlink support,
33   possibly as simple as through `git config core.symlinks true` or cloning with
34   `git clone -c core.symlinks=true <URL>`.
35 </details>
36
37 Install the [package dependencies](#package-dependencies):
38
39 ```
40 $ cabal install html regex-compat
41 ```
42
43 Then, to run the tests, execute:
44
45 ```
46 $ make clean # or git clean -fxd, it's faster
47 $ # Generates input files for the benchmarks and builds compilation
48 $ # dependencies for make (ghc -M)
49 $ make boot
50 $ # Builds the benchmarks and runs them $NoFibRuns (default: 5) times
51 $ make
52 ```
53
54 This will put the results in the file `nofib-log`. You can pass extra
55 options to a nofib run using the `EXTRA_HC_OPTS` variable like this:
56
57 ```
58 $ make clean
59 $ make boot
60 $ make EXTRA_HC_OPTS="-fllvm"
61 ```
62
63 To compare the results of multiple runs, save the output in a logfile
64 and use the program in `../utils/nofib-analyse`, for example:
65
66 ```
67 ...
68 $ make 2>&1 | tee nofib-log-6.4.2
69 ...
70 $ make 2>&1 | tee nofib-log-6.6
71 $ nofib-analyse nofib-log-6.4.2 nofib-log-6.6 | less
72 ```
73
74 to generate a comparison of the runs in captured in `nofib-log-6.4.2`
75 and `nofib-log-6.6`. When making comparisons, be careful to ensure
76 that the things that changed between the builds are only the things
77 that you _wanted_ to change. There are lots of variables: machine,
78 GHC version, GCC version, C libraries, static vs. dynamic GMP library,
79 build options, run options, and probably lots more. To be on the safe
80 side, make both runs on the same unloaded machine.
81
82 ## Modes
83
84 Each benchmark is runnable in three different time `mode`s:
85
86 - `fast`: 0.1-0.2s
87 - `norm`: 1-2s
88 - `slow`: 5-10s
89
90 You can control which mode to run by setting an additional `mode` variable for
91 `make`. The default is `mode=norm`. Example for `mode=fast`:
92
93 ```
94 $ make clean
95 $ make boot mode=fast
96 $ make mode=fast
97 ```
98
99 Note that the `mode`s set in `make boot` and `make` need to agree. Otherwise you
100 will get output errors, because `make boot` will generate input files for a
101 different `mode`. A more DRY way to control the `mode` would be
102
103 ```
104 $ make clean
105 $ export mode=fast
106 $ make boot
107 $ make
108 ```
109
110 As CPU architectures advance, the above running times may drift and
111 occasionally, all benchmarks will need adjustments.
112
113 Be aware that `nofib-analyse` will ignore the result if it falls below 0.2s.
114 This is the default of its `-i` option, which is of course incompatible with
115 `mode=fast`. In that case, you should just set `-i` as appropriate, even
116 deactivate it with `-i 0`.
117
118 ## Configuration
119
120 There are some options you might want to tweak; search for nofib in
121 `../mk/config.mk`, and override settings in `../mk/build.mk` as usual.
122
123 ## Extra Metrics: Valgrind
124
125 To get instruction counts, memory reads/writes, and "cache misses",
126 you'll need to get hold of Cachegrind, which is part of
127 [Valgrind](http://valgrind.org).
128
129 You can then pass `-cachegrind` as `EXTRA_RUNTEST_OPTS`. Counting
130 instructions slows down execution by a factor of ~30. But it's
131 a deterministic metric, so you can combine it with `NoFibRuns=1`:
132
133 ```
134 $ (make EXTRA_RUNTEST_OPTS="-cachegrind" NoFibRuns=1) 2>&1 | tee nofib-log
135 ```
136
137 Optionally combine this with `mode=fast`, see [Modes](#modes).
138
139 ## Extra Packages
140
141 Some benchmarks aren't run by default and require extra packages are
142 installed for the GHC compiler being tested. These packages include:
143  * stm - for smp benchmarks
144
145 ## Adding benchmarks
146
147 If you add a benchmark try to set the problem sizes for
148 fast/normal/slow reasonably. [Modes](#modes) lists the recommended brackets for
149 each mode.
150
151 ### Stability wrt. GC paramerisations
152
153 Additionally, pay attention that your benchmarks are stable wrt. different 
154 GC paramerisations, so that small changes in allocation don't lead to big,
155 unexplicable jumps in performance. See Trac #15999 for details. Also make sure
156 that you run the benchmark with the default GC settings, as enlarging Gen 0 or
157 Gen 1 heaps just amplifies the problem.
158
159 As a rule of thumb on how to ensure this: Make sure that your benchmark doesn't
160 just build up one big data and consume it in a final step, but rather that the
161 working set grows and shrinks (e.g. is approximately constant) over the whole
162 run of the benchmark. You can ensure this by iterating your main logic $n times
163 (how often depends on your program, but in the ball park of 100-1000).
164 You can test stability by plotting productivity curves for your `fast` settings
165 with the `prod.py` script attached to Trac #15999.
166
167 If in doubt, ask Sebastian Graf for help.