Skip to content

Commit c8000b6

Browse files
author
John McFarlane
committed
Submission of P1832R0
1 parent 6137920 commit c8000b6

File tree

2 files changed

+390
-63
lines changed

2 files changed

+390
-63
lines changed

wg21/p1832.md

+104-63
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,36 @@
1-
**Document number**: D1832R0
2-
**Date**: 2019-07-21
1+
**Document number**: P1832R0
2+
**Date**: 2019-08-05
33
**Reply-to**: John McFarlane, [[email protected]](mailto:[email protected])
44
**Audience**: SG6, SG14, SG15, SG19
55

66
# Improving Debug Builds Inline With User Expectation
77

88
## Abstract
99

10-
Users frequently complain that modern C++ abstractions
10+
Some users complain that modern C++ abstractions
1111
make it hard to debug their programs.
12-
This document explores some of the reasons for these complaints and
12+
This document explores one of the reasons for these complaints and
1313
suggests a possible solution for implementers.
1414

1515
## Introduction
1616

1717
This document is written in response to the assertion that
1818
"non-optimized build performance is important" as stated in the article,
1919
["Modern" C++ Lamentations](https://aras-p.info/blog/2018/12/28/Modern-C-Lamentations/).
20-
The article, written by a game developer, sparked
21-
[a discussion](https://groups.google.com/a/isocpp.org/d/topic/sg14/Zx3b2rgpYck/discussion)
22-
on the SG14 reflector which did not result in any action.
20+
The article, written by a game developer, sparked discussion
21+
on [social media](https://twitter.com/aras_p/status/1078682464602726400)
22+
and the [SG14 reflector](https://groups.google.com/a/isocpp.org/d/topic/sg14/Zx3b2rgpYck/discussion)
23+
which did not conclude with concrete action to be taken.
2324

2425
More recently, SG6 and SG14 reviewed linear algebra papers in Cologne
2526
and game development was identified as a target audience for these
26-
library components. Without any further action to address the assertion,
27+
library components.
28+
I opined that without any further action to address the assertion,
2729
those components — and an increasing proportion of the standard library
28-
as a whole — will be ignored by a growing number of C++ users.
30+
as a whole — would be rejected by a growing number of C++ users.
2931

30-
It is the author's view
31-
that the assertion forewarns of a scalability problem
32-
that C++ must address in order to remain relevant.
32+
It is my view that the assertion forewarns of a scalability problem
33+
that C++ must address in order to continue on its current course.
3334

3435
## Background
3536

@@ -38,60 +39,60 @@ that C++ must address in order to remain relevant.
3839
During the development cycle, it is common for C++ users to produce
3940
binaries that are optimised for testing and debugging. These are often
4041
called *debug builds* — to be contrasted with *release builds* which
41-
are optimised for performance.
42+
are optimised for production use.
4243

43-
It is accepted that the debug builds are bigger and execute more slowly
44+
It is accepted that debug builds are bigger and execute more slowly
4445
than release builds of the same program.
45-
They may include correctness checks, symbol information
46-
and debugging information.
46+
They may include correctness checks,
47+
and symbol and debugging information.
4748
They may also disable optimizations which
4849
hamper the compiler's ability to provide helpful debugging information.
4950

5051
### Function Inlining
5152

5253
A very common optimization which causes the loss of debugging
53-
information is *function inlining*. Function inlining effectively
54-
removes functions and, in doing so, removes debugging information
55-
associated with those functions. In particular, **debug builds disable
56-
function inlining**.
54+
information is *function inlining*.
55+
Function inlining effectively removes functions
56+
and, in doing so, removes or obscures debugging information
57+
associated with those functions.
5758

5859
The lack of function inlining is one reason why
5960
a debug build may be bigger and execute more slowly.
6061

6162
### Library-Based Abstractions
6263

63-
Unfortunately, an increasing number of C++ abstractions rely heavily on
64-
function inlining in order to maintain zero run-time overhead.
65-
They are found in — both standard library implementations and —
66-
third-party libraries. They are characterised by
64+
Unfortunately, a growing number of library-based abstractions
65+
rely on function inlining in order to maintain zero run-time overhead.
66+
Many libraries are affected, including the standard library.
67+
The abstractions are characterised by
6768
deep call trees which collapse down to efficient machine code.
6869

6970
### The Dilemma
7071

71-
Without function inlining, many library abstractions incur significant
72+
Without function inlining, these abstractions incur significant
7273
cost in terms of binary size and run-time performance.
7374
With function inlining, the same abstractions obfuscate
7475
stack traces and otherwise hamper the ability of tools to provide
7576
the user with helpful debugging information.
7677

77-
This causes a dilemma which is felt most acutely in abstractions which
78+
This causes a dilemma which is felt most acutely in abstractions that
7879
have the highest ratio of compile-time complexity to run-time code
7980
generation.
8081

81-
For example, many numerics libraries offer user-friendly abstractions
82+
For example, many numerics libraries offer abstractions
8283
over fundamental arithmetic types.
8384
A substantial amount of source code will routinely result in
8485
[a single arithmetic instruction](https://godbolt.org/z/easvxD).
85-
However, the problem is [ranges](https://godbolt.org/z/DHshRI)
86+
However, the problem [ranges](https://godbolt.org/z/DHshRI)
8687
far beyond purely arithmetic abstractions.
8788

8889
## Problem Analysis
8990

9091
### One User's Solution is Another User's Problem
9192

92-
One way in which **library designers attempt to address concerns over
93-
performance** of debug builds is to try and single out their functions
94-
for inlining. **This fails** for two reasons.
93+
One way in which library designers attempt to address concerns over
94+
performance of debug builds is to try and single out their functions
95+
for inlining. This fails for two reasons.
9596

9697
Firstly, explicit inlining as an optimization hint is a mistake.
9798
A modern tool chain does a far better job of determining
@@ -101,18 +102,18 @@ configuration and profile guidance. Assuming the user made the right
101102
choice on a given day (unlikely), the same choice may be wrong
102103
tomorrow.
103104

104-
Secondly, **the intent to inline is based on ownership of the
105-
function**. It's likely that users of the library DO wish for
106-
inlining of its functions in debug builds. Conversely, authors of the
105+
Secondly, the intent to inline is based on ownership of the
106+
function. It's likely that *users* of the library DO wish for
107+
inlining of its functions in debug builds. Conversely, *authors* of the
107108
library DO NOT wish for inlining of the very same functions. Hence, no
108109
annotation or keyword could possibly cover both use cases.
109110

110111
In short, explicit inlining is a bad tool for the wrong job.
111112

112-
### A C++ Problem
113+
### One of Several Problems for C++
113114

114115
A common feature of modern C++ functions is that they are delivered via
115-
header files. Equivalent traditional C++ and C functions would be
116+
header files. Comparable traditional C++ and C functions would be
116117
defined in source files, making it easy for the library author or
117118
library user to optimize them in isolation.
118119

@@ -123,9 +124,17 @@ may habitually chose the 'step into' facility of the debugger and
123124
automatically traverse the subsection of the call graph that is under
124125
their control.
125126

127+
This paper focuses on run-time performance of debug builds
128+
and not the quality of interactive debugging experience.
129+
However, it is a closely-related topic
130+
and this proposal hopes to improve it as a side effect.
131+
It has also been tackled by [IDEs](https://www.cprogramming.com/debugging/visual-studio-msvc-debugging-NoStepInto.html)
132+
and [GDB extensions](https://github.com/jefftrull/gdb_python_api)
133+
suggesting that is a problem worthy of attention in its own right.
134+
126135
### A Niche Problem
127136

128-
The problem is not only a technical one.
137+
The problem of debug build performance has a non-technical dimension.
129138

130139
Firstly, it affects programs where performance of debug builds is
131140
critical. This excludes batch programs and event-based user interfaces
@@ -134,44 +143,57 @@ where slower response to user input is not a deal-breaker.
134143
Secondly, it only affects developers who use debuggers. There is
135144
[disagreement](https://twitter.com/PeterSommerlad/status/1078958027175329793)
136145
about whether interactive debugging is even necessary in the era of
137-
test-driven development. But it is clear that they are deemed necessary
138-
by users in specific domains and have been for a long time.
146+
test-driven development. But it is clear that it is deemed necessary
147+
by users in specific domains and has been for a long time.
139148

140-
The necessity for interactive debugging in select domains and the
141-
reasons why this might pose a blind spot for the committee are not
142-
subjects covered here.
149+
It is plausible that developers
150+
who suffer most from debug build performance
151+
are not well represented within WG21.
152+
To them, the committee appears unsympathetic.
143153

144154
### Somebody Else's Problem
145155

146-
Where the standard adds features which cause pain to users, it adds
147-
injury to describe those features as a 'quality of implementation'
148-
issue. That description is both true and inadequate.
149-
Not only does the committee have an obligation
156+
Where the standard adds features which cause pain to users,
157+
it adds insult to injury by describing those features
158+
as a 'quality of implementation' issue.
159+
That description is both accurate and inadequate.
160+
Not only does the committee have a responsibility
150161
to deal with the consequences of its choices.
151-
But it also has a unique ability to mediate between users and implementors.
152-
Hopeful this is role that SG15 can fulfil.
162+
But it also has a unique ability
163+
to mediate between users and implementors.
164+
Hopeful this is a role that SG15 can fulfil.
153165

154166
### Conclusion of Problem Analysis
155167

156-
The direction C++ has been taking for a very long time is taking it in a
157-
direction which is causing some users an increasing number of
158-
productivity problems including:
168+
The course that C++ has been following for a long time
169+
takes it in a direction which is causing some users
170+
an increasing number of productivity problems including:
159171

160172
1. slow, bloated debug builds;
161-
2. back traces that include unwanted noise from extra-project code; and
162-
3. hard-to-step-through call graphs.
163-
164-
Function inlining largely addresses all of the above problems when
165-
applied to project dependencies at the expense of making 3) acute for
166-
the project code itself. This trade-off results in a dilemma.
167-
The author suggests that it is this dilemma which is the real problem.
173+
2. back traces that include unwanted noise from extra-project code;
174+
3. hard-to-step-through call graphs; and
175+
4. slow build times.
176+
177+
Function inlining mitigates 1), 2) and 3)
178+
but can also adversely affect 1), 3) and 4).
179+
Thus the user faces a dilemma
180+
for which we offer no satisfactory solution.
181+
The author suggests that — aside from 4) which is an pressing issue in
182+
its own right — it is the dilemma which deserves attention and not
183+
individual problems, 1), 2) and 3).
168184

169185
## Straw Man Solution
170186

171-
In order to stimulate discussion of a workable solution to The Dilemma,
172-
the following sub-section hypothesises a change to GCC (or Clang)
173-
which — if implementable — could provide a tool chain-only solution that
174-
could apply to existing source code unchanged.
187+
In order to stimulate discussion around
188+
a workable solution to the dilemma,
189+
the following sub-section hypothesises a change to popular tool chains
190+
which — if implementable — would provide
191+
an implementation-specific solution
192+
that could apply to existing source code unchanged.
193+
194+
The solution works by considering pre-existing information about
195+
the origin of a function definition and using it to solve the dilemma
196+
of whether or not to inline that function.
175197

176198
### Proposed Change to GCC Option, `-Og`
177199

@@ -228,8 +250,27 @@ headers.
228250

229251
## FAQ
230252

253+
Q: How does the proposed tool chain enhancement help?
254+
255+
A: It helps by drawing a distinction between the user's functions and
256+
the functions of a user's dependencies. It is assumed that the user
257+
only wishes to debug their own code and would rather optimise
258+
dependency code. Dependency code should already be included in the
259+
translation unit via a different header search path option. The
260+
compiler can use that change to make the choice to inline.
261+
262+
Q: Does this proposal work?
263+
264+
A: I have absolutely no idea. Optimising compilers are incredibly
265+
sophisticated and complex tools which I haven't devoted the time to
266+
understand. It is entirely possible, for example, that the
267+
architecture of a particular compiler makes it especially difficult
268+
to selectively enable and disable inlining on a per-function basis.
269+
But even if this technique worked half of the time, I posit that it
270+
would improve the situation for users.
271+
231272
Q: Why inlining, specifically, and not other optimizations which would
232-
make code from dependencies faster?
273+
make dependency code faster?
233274

234275
A: For the sake of simplicity, this paper concentrates on what the
235276
author believes is the single most significant optimization

0 commit comments

Comments
 (0)