Really? Odd. It's been a frequent talking point in my (outside the
committee) experience. It would be helpful to know if there are any
notes or minutes from the meeting it was presented at.
>
> It would be good to get an analysis update to see if many of the issues still remain or got worst or better with c++ 11/14. Add any new issues. Partition them as Sean said into low hanging fruit.
It is getting a little long in the tooth. Looking at the list of
motivations again, most of them have been taken care of (some only by
very recent commonly available compiler tech improvements).
My thoughts on the document now (these all need verification!):
- std STL allocators are painful to work with and lead to code bloat
and sub-optimal performance. This topic is addressed separately within
this document.
C++11 simplified allocators and the polymorphic allocator proposal
help here a lot. I've found that a lack of proper alignment support
and for more advanced allocation flags (e.g., clear to 0) annoying but
not show stoppers.
- Useful STL extensions (e.g. slist, hash_map, shared_ptr) found in
some std STL implementations are not portable because they don't exist
in other versions of STL or are inconsistent between STL versions
(though they are present in the current C++09 draft).
All three of those extensions are in C++11. We are still missing some
handy ones, though, like flat_map.
- The STL lacks functionality that game programmers find useful (e.g.
intrusive containers) and which could be best optimized in a portable
STL environment. See Appendix item 16.
Still true.
- Existing std STL implementations use deep function calls. This
results in low performance with compilers that are weak at inlining,
as is the currently prevalent open-source C++ compiler. See Appendix
item 15 andAppendix item 10.
All the major compilers today support inlining small accessor
functions evne in debug builds. This item needs measurement, though.
- Existing STL implementations are hard to debug. For example, you
typically cannot browse the contents of a std::list container with a
debugger due to std::list's usage of void pointers. On the other hand,
EASTL allows you to view lists without incurring a performance or
memory cost. See Appendix item 2.
Mostly a tools issue. Visual Studio for instance has a powerful debug
visualizer feature and supports its own STL out of the box. GDB has an
even more powerful debug visualizer and supports libstdc++ out of the
box.
- The STL doesn't explicitly support alignment requirements of
contained objects, yet non-default alignment requirements are common
in game development. A std STL allocator has no way of knowing the
alignment requirements of the objects it is being asked to allocate,
aside from compiler extensions. Granted, this is part of the larger
problem of the C++ language providing minimal support for alignment
requirements. Alignment support is proposed for C++09.
Use issue. The C++11 alignment issue has no effect on free-store
allocations. However, I think this might be less of a "we need
explicit alignment" issue and more "the native alignment should
include the SIMD/vector types of the CPU." (which in my experience yet
is the major reason I have to work around default allocation
alignments.)
- STL containers won't let you insert an entry into a container
without supplying an entry to copy from. This can be inefficient in
the case of elements that are expensive to construct.
emplace_back and move semantics.
- The STL implementations that are provided by compiler vendors for
the most popular PC and console (box connected to TV) gaming platforms
have performance problems. EASTL generally outperforms all existing
STL implementations; it does so partly due to algorithmic improvements
but mostly due to practical improvements that take into account
compiler and hardware behavior. See Appendix item 20.
Not the standard's fault... mostly.
One could make the case that the standard could be stricer about some
of these issues and not leave them all as QoI items. One that gets me
is small-object "optimizations" in things like std::string or
std::function. I can't rely on what size of data will or will not
trigger an allocation in a portable manner. It becomes worthwhile to
rewrite them just to get a consistent cross-platform cross-vendor
known semantics here.
- Existing STL implementations are hard to debug/trace, as some STL
implementations use cryptic variable names and unusual data structures
and have no code documentation. See Appendix item 2.
Still a common issue. This has some up in some proposals for allowing
certain headers to ignore user macros, which are mostly the reason
that these cryptic issues exist.
- STL containers have private implementations that don't allow you to
work with their data structures in a portable way, yet sometimes this
is an important thing to be able to do (e.g. node pools). See Appendix
item 22.
Not quite as relevant anymore, e.g. vector::data(). Needs more investigation.
- Many current versions of std STL allocate memory in empty versions
of at least some of their containers. This is not ideal and prevents
optimizations such as container memory resets that can significantly
increase performance in some situations. An empty container should
allocate no memory.
"Many" is an overstatement, but "any" is a problem. Might be another
issue where the standard needs to be stricter. I understand that some
standard containers actually have to do this for move operations and
the like, though, in order to not invalidate iterators. This might be
one of the cases similar to unordered_map where a small oversight in
the standardese hampered the usefulness of the container significantly
but is now embedded in stone.
- All current std STL algorithm implementations fail to support the
use of predicate references, which results in inefficient hacks to
work around the problem. See Appendix item 3.
There have been proposals for this, either directly or indirectly, but
focus on reviewing those and helping them through would be good.
- The STL puts an emphasis on correctness before practicality and
performance. This is an understandable policy but in some cases
(particularly std::allocator) it gets in the way of usability and
optimized performance.
This is a hard one. I think the correctness is the right choice as the
default. There are some cases where the standard could allow more
dangerous operations; see the discussions on
vector::push_back_no_grow() for instance.
> But I feel in there must be some common interest. I can help to get such a study group started, but likely won't be able to chair it as I already have too many titles. But Sean looks like he is doing a great job already. ...
It's unlikely I'll be able to as all indications I've received are
that my company is not interested in sending me to any meetings
outside of the Seattle area, at least until after our current title
ships (not until 2016 at the earliest).
--
Sean Middleditch
http://seanmiddleditch.com