3 ms·
> It's a bit more nuanced I think Yes, I have edited it a bit; I did not want to claim that unique_ptr is universally passed through the stack, just that it is
by AshamedCaptain 3y ago
> It's a bit more nuanced I think
Yes, I have edited it a bit; I did not want to claim that unique_ptr is universally passed through the stack, just that it is not an insurmontable problem to do so.
> this is again only the artifact of Itanium ABI and something C++ can only adhere to but cannot change. Any language that speaks to the system (OS) must do the same.
This is not true, though. 1) you can change and evolve this ABI (it has happened in the past), 2) you can also have an ABI for the system libraries and an ABI for the rest (see Windows, or see how any language other than C works), and 3) since the problem would only be about non-PODs, which are pretty much C++ specific, the system ABI would not be affected at all.
- menaerus 3y agoI see, thanks for clarifying, especially on number (2) which I wasn't aware of. I always had an impression that the compiler ABI is somewhat tightly coupled with the system ABI and which is why I used them almost interchangeably. So, Google premise is that they can provide alternative unique_ptr implementation in a way so that it breaks the C++ ABI without touching the Itanium ABI but with the benefit of unique_ptr fitting into the registers always rather than almost always? If so, I am not aware that they have shown any such implementation and its impact to their codebase?
- AshamedCaptain 3y agoYou won't be compatible with the SysV/Itanium ABI (it does include C++ bits), but you can definitely do it. It just happens that you will probably not have any problem to call a C library from such a new ABI (incl. libc and the kernel) since you only changed non-POD behavior, and those C libraries won't use anything but PODs. The fact that you can have some structs with non-trivial methods that are still classified as PODs means the ABI is already solving the hard problem (i.e. these methods won't really have a 'this' pointer), so the limitation for types like unique_ptr sounds like easy to remove in an experiment.
- menaerus 3y agoSo ... it appears that LLVM actually did the necessary code changes - libc++ with [[clang::trivial_abi]] on std::unique_ptr guarantees that the std::unique_ptr is always going to be passed directly through a register: https://libcxx.llvm.org/DesignDocs/UniquePtrTrivialAbi.html https://libcxx.llvm.org/DesignDocs/UniquePtrTrivialAbi.html Caveats outlined by the document: > Function definitions now require complete type T for parameters with type std::unique_ptr<T>. The following code will no longer compile. > Lifetime of std::unique_ptr<> arguments end earlier (at the end of the callee’s body, rather than at the end of the full expression containing the call). > Lifetime of local returned std::unique_ptr<> ends earlier. So, switch to a new ABI alone requires (1) a lot of manual code plumbing, e.g. replacing all your std::unique_ptr with forward-declared types with corresponding header includes across the whole codebase and (2) more serious session of discovering and fixing new std::unique_ptr runtime behavior using ASAN. Benefits of this ABI change measured on the Google-scale? This is what they have to say: > Google has measured performance improvements of up to 1.6% on some large server macrobenchmarks, and a small reduction in binary sizes. IMO pretty serious caveats for no obvious benefits, even at such a large scale as Google. Measuring 1.6% of runtime performance benefit on macro-scale is hard, if not impossible, to differentiate from measuring the noise.