Open Quuxplusone opened 9 years ago
Bugzilla Link | PR23652 |
Status | NEW |
Importance | P normal |
Reported by | Niall Douglas (s_bugzilla@nedprod.com) |
Reported on | 2015-05-25 19:03:49 -0700 |
Last modified on | 2015-06-11 08:51:38 -0700 |
Version | trunk |
Hardware | PC Linux |
CC | anton@korobeynikov.info, chandlerc@gmail.com, llvm-bugs@lists.llvm.org |
Fixed by commit(s) | |
Attachments | |
Blocks | |
Blocked by | |
See also |
An update to this bug: the Microsoft Visual Studio team have very kindly helped
me get this code to persuade MSVC to collapse these lightweight future promises
into no opcodes output, and the current stats are as follows for x64 opcodes
generated for each of these tests:
GCC 5.1 VS2015 clang 3.7
future_construct_destruct.cpp 0 3 7
future_construct_move_destruct.cpp 0 3 18
monad_construct_destruct.cpp 0 3 0
monad_construct_value_destruct.cpp 1 4 33
promise_construct_destruct.cpp 0 3 6
promise_construct_move_destruct.cpp 0 3 18
promise_future_reduce.cpp 1 3111 32
GCC has *perfect* results. The terrible result for promise_future_reduce on
VS2015 is hoped to be fixed by Microsoft shortly after RTM.
This now makes clang 3.7 look particularly poor relative to GCC and MSVC.
I'll give you fair warning now: I expect to present on these at C++ conferences
in Bristol and Seattle from Spring 2016 onwards. If clang is still performing
poorly relative to the others, I'll say so publicly, and with benchmarks.
Niall
(In reply to comment #1)
> GCC has *perfect* results. The terrible result for promise_future_reduce on
> VS2015 is hoped to be fixed by Microsoft shortly after RTM.
>
> This now makes clang 3.7 look particularly poor relative to GCC and MSVC.
More useful information for this bug report. For just the monadic transport
only, here are the best case and worst case opcode generation results:
clang 3.7
59 opcodes <= Value transport <= 37 opcodes
7 opcodes <= Error transport <= 52 opcodes
38 opcodes <= Exception transport <= 39 opcodes
GCC 5.1
1 opcodes <= Value transport <= 113 opcodes
8 opcodes <= Error transport <= 119 opcodes
22 opcodes <= Exception transport <= 214 opcodes
VS2015
4 opcodes <= Value transport <= 1881 opcodes
6 opcodes <= Error transport <= 164 opcodes
1946 opcodes <= Exception transport <= 1936 opcodes
The maximum is calculated by taking a monad in from a non-visible source where
the compiler has to generate all code paths to handle an unknown (variant)
input state, whereas the minimum is calculated by setting a monad's state in
view of the compiler's optimiser such that it can usually completely elide
opcodes generated (though note that varies enormously by compiler to the extent
that the known code generates more opcodes than the unknown code). From an
optimiser's perspective, in the minimum case it can elide all code paths
forwards which could never be executed anyway, whilst for the maximum case it
can elide all code paths backwards on the basis that the only two outcomes are
fetching the value/error/exception or throwing an exception.
In terms of maximum opcodes generated, clang 3.7 does very well indeed, and the
best of any of the compilers showing it optimises backwards very well. GCC 5.1
does the best in minimum opcodes generated showing it optimises forwards very
well. VS2015 is somewhere between great and terrible, though it has no choice
if an exception_ptr is ever touched as Microsoft require some unfortunately
very hard memory effects due to backward ABI compatibility.
If you could get clang's minimum case (forward optimisation) as good as GCC,
that would be enormous.
Niall