]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/libs/leaf/benchmark/benchmark.md
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / leaf / benchmark / benchmark.md
index e1dc49052cd390de1c229c74999126db08ff90f2..0ae9b3328e1747debbe6402650e6bbd42baa329e 100644 (file)
@@ -13,9 +13,9 @@ LEAF serves a similar purpose to other error handling libraries, but its design
 
 The main design difference is that when using LEAF, error objects are not communicated in return values. In case of a failure, the `leaf::result<T>` object transports only an `int`, the unique error ID.
 
-Error objects skip the error-neutral functions in the call stack and get moved directly to the the error-handling scope that needs them. This mechanism does not depend on RVO or any other optimization: as soon as the program passes an error object to LEAF, it moves it to the correct error handling scope.
+Error objects skip the error neutral functions in the call stack and get moved directly to the the error handling scope that needs them. This mechanism does not depend on RVO or any other optimization: as soon as the program passes an error object to LEAF, it moves it to the correct error handling scope.
 
-Other error-handling libraries instead couple the static type of the return value of *all* error-neutral functions with the error type an error-reporting function may return. This approach suffers from the same problems as statically-enforced exception specifications:
+Other error handling libraries instead couple the static type of the return value of *all* error neutral functions with the error type an error reporting function may return. This approach suffers from the same problems as statically-enforced exception specifications:
 
 * It's difficult to use in polymorphic function calls, and
 * It  impedes interoperability between the many different error types any non-trivial program must handle.
@@ -122,11 +122,11 @@ Which on clang 9 outputs:
 
 ```x86asm
 val():
-       mov     eax, 42
-       ret
+        mov     eax, 42
+          ret
 main:
-       mov     eax, 42
-       ret
+        mov     eax, 42
+        ret
 ```
 
 It does not appear that anything like this is occurring in our case, but it is still a possibility.
@@ -150,48 +150,48 @@ leaf::result<int> g()
 }
 ```
 
-Generates this code on clang ([Godbolt](https://godbolt.org/z/aMh4zo)):
+Generates this code on clang ([Godbolt](https://godbolt.org/z/v58drTPhq)):
 
 ```x86asm
 g():                                  # @g()
-       push    rbx
-       sub     rsp, 32
-       mov     rbx, rdi
-       mov     rdi, rsp
-       call    f()
-       mov     eax, dword ptr [rsp + 16]
-       mov     ecx, eax
-       and     ecx, 3
-       cmp     ecx, 2
-       je      .LBB0_3
-       cmp     ecx, 3
-       jne     .LBB0_4
-       mov     eax, dword ptr [rsp]
-       add     eax, 1
-       mov     dword ptr [rbx], eax
-       mov     eax, 3
-       jmp     .LBB0_4
+        push    rbx
+        sub     rsp, 32
+        mov     rbx, rdi
+        lea     rdi, [rsp + 8]
+        call    f()
+        mov     eax, dword ptr [rsp + 24]
+        mov     ecx, eax
+        and     ecx, 3
+        cmp     ecx, 3
+        jne     .LBB0_1
+        mov     eax, dword ptr [rsp + 8]
+        add     eax, 1
+        mov     dword ptr [rbx], eax
+        mov     eax, 3
+        jmp     .LBB0_3
+.LBB0_1:
+        cmp     ecx, 2
+        jne     .LBB0_3
+        mov     rax, qword ptr [rsp + 8]
+        mov     qword ptr [rbx], rax
+        mov     rax, qword ptr [rsp + 16]
+        mov     qword ptr [rbx + 8], rax
+        mov     eax, 2
 .LBB0_3:
-       movaps  xmm0, xmmword ptr [rsp]
-       mov     qword ptr [rsp + 8], 0
-       movups  xmmword ptr [rbx], xmm0
-       mov     qword ptr [rsp], 0
-       mov     eax, 2
-.LBB0_4:
-       mov     dword ptr [rbx + 16], eax
-       mov     rax, rbx
-       add     rsp, 32
-       pop     rbx
-       ret
+        mov     dword ptr [rbx + 16], eax
+        mov     rax, rbx
+        add     rsp, 32
+        pop     rbx
+        ret
 ```
 
 > Description:
 >
 > * The happy path can be recognized by the `add eax, 1` instruction generated for `x + 1`.
 >
-> * `.LBB0_4`: Regular failure; the returned `result<T>` object holds only the `int` discriminant.
+> * `.LBB0_3`: Regular failure; the returned `result<T>` object holds only the `int` discriminant.
 >
-> * `.LBB0_3`: Failure; the returned `result<T>` holds the `int` discriminant and a `std::shared_ptr<leaf::polymorphic_context>` (used to hold error objects transported from another thread).
+> * `.LBB0_1`: Failure; the returned `result<T>` holds the `int` discriminant and a `std::shared_ptr<leaf::polymorphic_context>` (used to hold error objects transported from another thread).
 
 Note that `f` is undefined, hence the `call` instruction. Predictably, if we provide a trivial definition for `f`:
 
@@ -212,10 +212,10 @@ We get:
 
 ```x86asm
 g():                                  # @g()
-       mov     rax, rdi
-       mov     dword ptr [rdi], 43
-       mov     dword ptr [rdi + 16], 3
-       ret
+          mov     rax, rdi
+          mov     dword ptr [rdi], 43
+          mov     dword ptr [rdi + 16], 3
+          ret
 ```
 
 With a less trivial definition of `f`:
@@ -236,32 +236,32 @@ leaf::result<int> g()
 }
 ```
 
-We get ([Godbolt](https://godbolt.org/z/nezE7s)):
+We get ([Godbolt](https://godbolt.org/z/87Kezzrs4)):
 
 ```x86asm
 g():                                  # @g()
-       push    rbx
-       mov     rbx, rdi
-       call    rand
-       test    al, 1
-       jne     .LBB1_2
-       mov     eax, 4
-       lock xadd dword ptr [rip + boost::leaf::leaf_detail::id_factory<void>::counter], eax
-       add     eax, 4
-       mov     dword ptr fs:[boost::leaf::leaf_detail::id_factory<void>::current_id@TPOFF], eax
-       and     eax, -4
-       or      eax, 1
-       mov     dword ptr [rbx + 16], eax
-       mov     rax, rbx
-       pop     rbx
-       ret
+        push    rbx
+        mov     rbx, rdi
+        call    rand
+        test    al, 1
+        jne     .LBB1_2
+        mov     eax, 4
+        lock            xadd    dword ptr [rip + boost::leaf::leaf_detail::id_factory<void>::counter], eax
+        add     eax, 4
+        mov     dword ptr fs:[boost::leaf::leaf_detail::id_factory<void>::current_id@TPOFF], eax
+        and     eax, -4
+        or      eax, 1
+        mov     dword ptr [rbx + 16], eax
+        mov     rax, rbx
+        pop     rbx
+        ret
 .LBB1_2:
-       mov     dword ptr [rbx], 43
-       mov     eax, 3
-       mov     dword ptr [rbx + 16], eax
-       mov     rax, rbx
-       pop     rbx
-       ret
+        mov     dword ptr [rbx], 43
+        mov     eax, 3
+        mov     dword ptr [rbx + 16], eax
+        mov     rax, rbx
+        pop     rbx
+        ret
 ```
 
 Above, the call to `f()` is inlined:
@@ -285,7 +285,7 @@ The benchmark matrix has 2 dimensions:
 
 Now, transporting a large error object might seem unusual, but this is only because it is impractical to return a large object as *the* return value in case of an error. LEAF has two features that make communicating any, even large error objects, practical:
 
-* The return type of error-neutral functions is not coupled with the error object types that may be reported. This means that in case of a failure, any function can easily contribute any error information it has available.
+* The return type of error neutral functions is not coupled with the error object types that may be reported. This means that in case of a failure, any function can easily contribute any error information it has available.
 
 * LEAF will only bother with transporting a given error object if an active error handling scope needs it. This means that library functions can and should contribute any and all relevant information when reporting a failure, because if the program doesn't need it, it will simply be discarded.
 
@@ -297,23 +297,22 @@ Now, transporting a large error object might seem unusual, but this is only beca
 
 ## Godbolt
 
-Godbolt has built-in support for Boost (Outcome), but LEAF and `tl::expected` both provide a single header, which makes it very easy to use them online as well. To see the generated code for the benchmark program, you can copy and paste the following into Godbolt:
+Godbolt has built-in support for Boost (Outcome/LEAF), but `tl::expected` both provide a single header, which makes it very easy to use them online as well. To see the generated code for the benchmark program, you can copy and paste the following into Godbolt:
 
-`leaf::result<T>` ([godbolt](https://godbolt.org/z/Thdq1d))
+`leaf::result<T>` ([godbolt](https://godbolt.org/z/1hqqnfhMf))
 
 ```c++
-#include "https://raw.githubusercontent.com/boostorg/leaf/master/include/boost/leaf.hpp"
 #include "https://raw.githubusercontent.com/boostorg/leaf/master/benchmark/deep_stack_leaf.cpp"
 ```
 
-`tl::expected<T, E>` ([godbolt](https://godbolt.org/z/sHwtTU))
+`tl::expected<T, E>` ([godbolt](https://godbolt.org/z/6dfcdsPcc))
 
 ```c++
 #include "https://raw.githubusercontent.com/TartanLlama/expected/master/include/tl/expected.hpp"
 #include "https://raw.githubusercontent.com/boostorg/leaf/master/benchmark/deep_stack_other.cpp"
 ```
 
-`outcome::result<T, E>` ([godbolt](https://godbolt.org/z/ZrfRRA))
+`outcome::result<T, E>` ([godbolt](https://godbolt.org/z/jMEfGMrW9))
 
 ```c++
 #define BENCHMARK_WHAT 1
@@ -331,7 +330,7 @@ To build both versions of the benchmark program, the compilers are invoked using
 
 In addition, the LEAF version is compiled with:
 
-* `-DBOOST_LEAF_DIAGNOSTICS=0`: Disable diagnostic information for error objects not recognized by the program. This is a debugging feature, see [Configuration Macros](https://boostorg.github.io/leaf/#_configuration_macros).
+* `-DBOOST_LEAF_CFG_DIAGNOSTICS=0`: Disable diagnostic information for error objects not recognized by the program. This is a debugging feature, see [Configuration Macros](https://boostorg.github.io/leaf/#configuration).
 
 ## Results