Date: Thu, 15 Aug 2024 20:46:57 +0200
Another is QoI, as we can replace `&&` with `&` without breaking the program
then the compiler can do the same.
Of course this is not always correct like for `u && u->foo == x` but in many
cases As-If rules allow many transformations.
czw., 15 sie 2024 o 20:43 Nathaniel Rupprecht via Std-Proposals
<std-proposals_at_[hidden]> napisał(a):
>
> The classic solution to this would be to use the bit-wise logical operators (r.g. & | ^) that do not have any shortcutting. This will do exactly as you are proposing.
>
> On Thu, Aug 15, 2024 at 2:40 PM Robin Savonen Söderholm via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>
>> Hi!
>>
>> I saw a CPP-con talk a while ago about how the shortcutting logical operations may generate several branches that in some cases may hurt performance. E.g. if we have the function like:
>> ```cpp
>> inline int foo(int a, int b) {
>> if(a > 0 && b != 0) { return 0; } else { return 1; }
>> }
>> ```
>> , the compiler may be forced to create 2 rather than 1 branch here (a jump for the condition for "a" and a second jump for the condition of "b").
>> If we have this in a tight loop we may get various problems with performance. (I am aware of the branch predictor in modern processors, but still, the predictor has it's limitations and I also do work on embedded processors that may not even have a branch predictor, not to mention real-time systems as well...) I am looking for a relatively easy way to say "just make one branch of this".
>> For example, we could have something along the lines of:
>> ```cpp
>> template <boolean-testable... Ts>
>> constexpr bool no_shortcut_and(Ts&&... vs) {
>> constexpr auto bool_to_int = [] (auto&& v) {
>> // If we know our compiler, we can guarantee that this is generated without a branch.
>> return v ? 1u : 0u;
>> };
>> // Once again, if we know our compiler, we can assume that this bit-wise operation is done without any extra branches.
>> return ( bool_to_int(std::forward<Ts>(vs) & ... & 1) == 1;
>> }
>>
>> // To show it's usage:
>>
>> inline int foo(int a, int b) {
>> if(std::no_shortcut_and(a > 0, b != 0)) { return 0; } else { return 1; }
>> }
>> ```
>> , and similar things for or and xor (disclaimer: I have not tested the code above, it is simply a prototype of what I think should work). But we could maybe figure out some way using generator expressions or similar to make it easier/more readable to use.
>>
>> This is barely a proposal but rather a "concept" of what I would like to have that should not be too easy to implement, but I feel no need to research deeply into the subject before I know that not something similar already exists or is on its way into the standard.
>>
>> // With best regards, Robin
>>
>>
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
then the compiler can do the same.
Of course this is not always correct like for `u && u->foo == x` but in many
cases As-If rules allow many transformations.
czw., 15 sie 2024 o 20:43 Nathaniel Rupprecht via Std-Proposals
<std-proposals_at_[hidden]> napisał(a):
>
> The classic solution to this would be to use the bit-wise logical operators (r.g. & | ^) that do not have any shortcutting. This will do exactly as you are proposing.
>
> On Thu, Aug 15, 2024 at 2:40 PM Robin Savonen Söderholm via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>
>> Hi!
>>
>> I saw a CPP-con talk a while ago about how the shortcutting logical operations may generate several branches that in some cases may hurt performance. E.g. if we have the function like:
>> ```cpp
>> inline int foo(int a, int b) {
>> if(a > 0 && b != 0) { return 0; } else { return 1; }
>> }
>> ```
>> , the compiler may be forced to create 2 rather than 1 branch here (a jump for the condition for "a" and a second jump for the condition of "b").
>> If we have this in a tight loop we may get various problems with performance. (I am aware of the branch predictor in modern processors, but still, the predictor has it's limitations and I also do work on embedded processors that may not even have a branch predictor, not to mention real-time systems as well...) I am looking for a relatively easy way to say "just make one branch of this".
>> For example, we could have something along the lines of:
>> ```cpp
>> template <boolean-testable... Ts>
>> constexpr bool no_shortcut_and(Ts&&... vs) {
>> constexpr auto bool_to_int = [] (auto&& v) {
>> // If we know our compiler, we can guarantee that this is generated without a branch.
>> return v ? 1u : 0u;
>> };
>> // Once again, if we know our compiler, we can assume that this bit-wise operation is done without any extra branches.
>> return ( bool_to_int(std::forward<Ts>(vs) & ... & 1) == 1;
>> }
>>
>> // To show it's usage:
>>
>> inline int foo(int a, int b) {
>> if(std::no_shortcut_and(a > 0, b != 0)) { return 0; } else { return 1; }
>> }
>> ```
>> , and similar things for or and xor (disclaimer: I have not tested the code above, it is simply a prototype of what I think should work). But we could maybe figure out some way using generator expressions or similar to make it easier/more readable to use.
>>
>> This is barely a proposal but rather a "concept" of what I would like to have that should not be too easy to implement, but I feel no need to research deeply into the subject before I know that not something similar already exists or is on its way into the standard.
>>
>> // With best regards, Robin
>>
>>
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Received on 2024-08-15 18:47:10