|
| 1 | +--- |
| 2 | +type: pitfall |
| 3 | +title: "Ball and Stick spent most of its frame in the bond-cap test, O(atoms x bonds); the test itself is not a start/count range test" |
| 4 | +area: wx-viewer |
| 5 | +paths: [src/inv/moiv/ChemUnitCylinder.C, src/inv/moiv/ChemDisplay.C, include/inv/ChemKit/ChemDisplay.H, src/viz/sgcommands/SGContainer.C, tools/viewer-bench/viewer-bench.C] |
| 6 | +issues: [224] |
| 7 | +--- |
| 8 | +`ChemUnitCylinder::render`, `renderHalfBonded` and |
| 9 | +`renderWithInterpolatedColor` ask, per bond end, whether to draw the |
| 10 | +cylinder's end cap (`PRE_RENDER_CAP`). That test scanned every entry of |
| 11 | +`ChemDisplay::atomIndex`, and `SGContainer` fills `atomIndex` with one |
| 12 | +`(atom, 1)` entry per atom, so a frame cost atoms x bonds field reads: |
| 13 | +about 800M instructions per frame for the 5184-atom water box, which is |
| 14 | +the gap between Ball and Stick (171 ms on an RTX 3050) and CPK (20 ms). |
| 15 | +Now `ChemDisplay::GLRender` reduces `atomIndex` to two bounds once per |
| 16 | +frame and `bondCapAtAtom()` answers in O(1). |
| 17 | + |
| 18 | +The old test matches an entry when `count == -1 && atom >= start`, or |
| 19 | +when `atom <= start && atom <= count`, which is not "atom lies in |
| 20 | +[start, start+count)". With per-atom entries only atoms 0 and 1 lose their |
| 21 | +caps; every other cap is drawn inside its sphere. `bondCapAtAtom` keeps |
| 22 | +that result exactly; fixing the test would draw less but can change pixels, |
| 23 | +so check it with `tools/coin/scenes/styles.scene` (`waterbox` too) first. |
| 24 | + |
| 25 | +The sibling `ADJUST_CYLINDER` in `ChemDisplayCylinders*.C` has the same |
| 26 | +range test but breaks on the first non-matching entry, so it is cheap. |
| 27 | + |
| 28 | +Measuring: `BENCH_STYLES="CPK,Ball And Stick,..."` runs only the water |
| 29 | +box. On llvmpipe the frame time is dominated by rasterisation and is too |
| 30 | +noisy under load to show this; count instructions instead |
| 31 | +(`valgrind --tool=callgrind --toggle-collect='ChemDisplay::GLRender*'`). |
| 32 | +`perf` is not available to users on Debian (`perf_event_paranoid=3`). |
| 33 | +`GALLIUM_NOOP=1` makes the benchmark exit silently. |
0 commit comments