Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #4812 > unrolled thread

Short-circuiting in C

Started byBilly Mays <noway@nohow.com>
First post2011-05-26 13:58 -0400
Last post2011-06-02 21:05 -0400
Articles 19 on this page of 59 — 23 participants

Back to article view | Back to comp.lang.c


Contents

  Short-circuiting in C Billy Mays <noway@nohow.com> - 2011-05-26 13:58 -0400
    Re: Short-circuiting in C Ben Pfaff <blp@cs.stanford.edu> - 2011-05-26 11:09 -0700
      Re: Short-circuiting in C Thomas Richter <thor@math.tu-berlin.de> - 2011-05-26 20:22 +0200
        Re: Short-circuiting in C Ben Pfaff <blp@cs.stanford.edu> - 2011-05-26 11:35 -0700
          Re: Short-circuiting in C falk@rahul.net (Edward A. Falk) - 2011-05-31 18:45 +0000
            Re: Short-circuiting in C Nizumzen <chicken@mcnuggets.com> - 2011-05-31 20:31 +0100
        Re: Short-circuiting in C Billy Mays <noway@nohow.com> - 2011-05-26 14:51 -0400
          Re: Short-circuiting in C Billy Mays <noway@nohow.com> - 2011-05-26 15:10 -0400
            Re: Short-circuiting in C Billy Mays <noway@nohow.com> - 2011-05-26 21:35 -0400
              Re: Short-circuiting in C Keith Thompson <kst-u@mib.org> - 2011-05-26 23:38 -0700
                Re: Short-circuiting in C Shao Miller <sha0.miller@gmail.com> - 2011-05-27 09:28 -0400
            Re: Short-circuiting in C falk@rahul.net (Edward A. Falk) - 2011-05-31 19:01 +0000
              Re: Short-circuiting in C falk@rahul.net (Edward A. Falk) - 2011-05-31 19:02 +0000
          Re: Short-circuiting in C Keith Thompson <kst-u@mib.org> - 2011-05-26 12:55 -0700
            Re: Short-circuiting in C Billy Mays <noway@nohow.com> - 2011-05-26 16:17 -0400
              Re: Short-circuiting in C Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-05-26 21:28 -0400
                Re: Short-circuiting in C Seebs <usenet-nospam@seebs.net> - 2011-05-27 05:06 +0000
                Re: Short-circuiting in C Noob <root@127.0.0.1> - 2011-05-27 17:48 +0200
                  Re: Short-circuiting in C Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-05-27 21:31 -0400
                Re: Short-circuiting in C blmblm@myrealbox.com <blmblm.myrealbox@gmail.com> - 2011-05-28 03:28 +0000
                  Re: Short-circuiting in C Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-05-27 23:43 -0400
                    Re: Short-circuiting in C blmblm@myrealbox.com <blmblm.myrealbox@gmail.com> - 2011-05-28 19:31 +0000
                    Re: Short-circuiting in C Michael Press <rubrum@pacbell.net> - 2011-05-30 00:28 -0700
                      Re: Short-circuiting in C BGB <cr88192@hotmail.com> - 2011-05-30 23:08 -0700
                        Re: Short-circuiting in C Michael Press <rubrum@pacbell.net> - 2011-05-31 18:30 -0700
                          Re: Short-circuiting in C BGB <cr88192@hotmail.com> - 2011-06-02 09:08 -0700
                  Re: Short-circuiting in C Nobody <nobody@nowhere.com> - 2011-05-28 14:08 +0100
                    Re: Short-circuiting in C BGB <cr88192@hotmail.com> - 2011-05-28 12:52 -0700
                Re: Short-circuiting in C falk@rahul.net (Edward A. Falk) - 2011-05-31 19:22 +0000
                  Re: Short-circuiting in C Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-05-31 21:07 -0400
                    Re: Short-circuiting in C Dr Nick <3-nospam@temporary-address.org.uk> - 2011-06-11 17:07 +0100
                      Re: Short-circuiting in C Shao Miller <sha0.miller@gmail.com> - 2011-06-11 12:57 -0500
    Re: Short-circuiting in C "Morris Keesan" <mkeesan@post.harvard.edu> - 2011-05-26 14:36 -0400
    Re: Short-circuiting in C "Scott Fluhrer" <sfluhrer@ix.netcom.com> - 2011-05-26 14:39 -0400
      Re: Short-circuiting in C Keith Thompson <kst-u@mib.org> - 2011-05-26 13:28 -0700
        Re: Short-circuiting in C Urist Sethkab <uristqwerty@gmail.com> - 2011-05-26 15:34 -0700
          Re: Short-circuiting in C "Scott Fluhrer" <sfluhrer@ix.netcom.com> - 2011-05-27 10:08 -0400
            Re: Short-circuiting in C Keith Thompson <kst-u@mib.org> - 2011-05-27 07:56 -0700
            Re: Short-circuiting in C Geoff <geoff@invalid.invalid> - 2011-05-27 20:14 -0700
              Re: Short-circuiting in C Keith Thompson <kst-u@mib.org> - 2011-05-27 20:26 -0700
                Re: Short-circuiting in C Geoff <geoff@invalid.invalid> - 2011-05-27 20:44 -0700
    Re: Short-circuiting in C Nobody <nobody@nowhere.com> - 2011-05-27 00:06 +0100
      Re: Short-circuiting in C Billy Mays <noway@nohow.com> - 2011-05-26 21:34 -0400
        Re: Short-circuiting in C Nobody <nobody@nowhere.com> - 2011-05-27 07:41 +0100
    Re: Short-circuiting in C Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-05-26 21:21 -0400
    Re: Short-circuiting in C Shao Miller <sha0.miller@gmail.com> - 2011-05-26 20:41 -0500
      Re: Short-circuiting in C Shao Miller <sha0.miller@gmail.com> - 2011-05-26 21:03 -0500
        Re: Short-circuiting in C Shao Miller <sha0.miller@gmail.com> - 2011-05-26 21:37 -0500
    Re: Short-circuiting in C ImpalerCore <jadill33@gmail.com> - 2011-05-27 09:01 -0700
      Re: Short-circuiting in C Willem <willem@toad.stack.nl> - 2011-05-27 16:08 +0000
        Re: Short-circuiting in C ImpalerCore <jadill33@gmail.com> - 2011-05-27 09:46 -0700
          Re: Short-circuiting in C BGB <cr88192@hotmail.com> - 2011-05-28 13:27 -0700
    Re: Short-circuiting in C James Kuyper <jameskuyper@verizon.net> - 2011-05-28 09:44 -0400
      Re: Short-circuiting in C Keith Thompson <kst-u@mib.org> - 2011-05-28 12:15 -0700
        Re: Short-circuiting in C James Kuyper <jameskuyper@verizon.net> - 2011-05-28 17:07 -0400
    Re: Short-circuiting in C "Herbert Rosenau" <os2guy@pc-rosenau.de> - 2011-05-29 07:25 +0000
    Re: Short-circuiting in C falk@rahul.net (Edward A. Falk) - 2011-05-31 18:40 +0000
      Re: Short-circuiting in C BGB <cr88192@hotmail.com> - 2011-06-02 09:48 -0700
        Re: Short-circuiting in C Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-06-02 21:05 -0400

Page 3 of 3 — ← Prev page 1 2 [3]


#4895

FromGeoff <geoff@invalid.invalid>
Date2011-05-27 20:44 -0700
Message-ID<var0u6tn80nqiiecb2fsemq2069gngo5vt@4ax.com>
In reply to#4893
On Fri, 27 May 2011 20:26:36 -0700, Keith Thompson <kst-u@mib.org>
wrote:

>Geoff <geoff@invalid.invalid> writes:
>> On Fri, 27 May 2011 10:08:58 -0400, "Scott Fluhrer"
>> <sfluhrer@ix.netcom.com> wrote:
>>
>>>Well, it has a different meaning:
>>>    a && b && c   is true if the three variables are all non-zero
>>>    !(a | b | c)   is true if all three variables are zero
>>
>> This looks suspiciously like De Morgan's theorem but the correct
>> expression of it would have been:
>>
>> !(!a || !b || !c)
>>
>> Why is everyone changing a logical operator into a bitwise operator
>> for this functionality without consideration for the values of the
>> operands?
>
>Not everyone is; most of us are specifically allowing for the
>possibility of values other than 0 and 1.
>

I was using the common "everyone" not the royal everyone. ;)

>> If we take the OP at face value and say, "how to short-circuit the
>> evaluation" of:
>>
>> if(a && b && c) {
>>      /* Do stuff */
>> }
>>
>> It seems to me the correct answer is:
>>
>> {
>>      /* Do stuff */
>> }
>>
>> Because if multiple threads or parallel processors are expected to
>> operate unconditionally on chunks of data with the same chunk of code
>> regardless of the values of three input variables then there is no
>> reason to initially evaluate the variables because they won't
>> influence the order of execution.
>
>I think the OP is trying to minimize branching, not eliminate it
>altogether.  An ideal solution to his problem would be an operator
>that acts like && except that it doesn't short-circuit (if C had
>such an operator).  The branching implied by the "if" is unavoidable.
>
>Hmm.
>
>static inline int and(x, y) { return !!x & !!y; }
>
>if (and(and(a, b), c)) {
>    /* Do stuff */
>}
>
>(untested)
>
>On the other hand, the OP had said this code is running on a GPU,
>and he's using a specialized compiler for a language very similar to
>C, but not quite C.  It could be that others have run into similar
>issue, and that the tools he's already using provide better solutions
>than anything we C folks can come up with.

I agree, a parallelized language targeting a specific processor would
know how to optimize for this or have a non-shorting boolean operator.

It also occurred to me that if the price of branching such a processor
is so steep it would probably be less costly to operate on the data
unconditionally even when the values are all zero, allowing some kind
of trap to occur in the thread if division by zero occurred. Such an
event4 might be a rarity and the impact on performance minimal in a
GPU.

[toc] | [prev] | [next] | [standalone]


#4851

FromNobody <nobody@nowhere.com>
Date2011-05-27 00:06 +0100
Message-ID<pan.2011.05.26.23.06.27.516000@nowhere.com>
In reply to#4812
On Thu, 26 May 2011 13:58:59 -0400, Billy Mays wrote:

> I was wondering if there is a way to avoid the C short circuiting for 
> boolean expressions such as the following:
> 
> if(a && b && c) {
>      /* Do stuff */
> }
> 
> I am currently doing GPU programming and it would be better to evaluate 
> the entire condition, even if a is 0, since branches are slow.

How does GPU programming relate to C programming?

Sure, GLSL/HLSL/Cg are "C-like" languages, but they aren't C.

[toc] | [prev] | [next] | [standalone]


#4854

FromBilly Mays <noway@nohow.com>
Date2011-05-26 21:34 -0400
Message-ID<irmv36$4o3$1@speranza.aioe.org>
In reply to#4851
On 5/26/2011 7:06 PM, Nobody wrote:
> On Thu, 26 May 2011 13:58:59 -0400, Billy Mays wrote:
>
>> I was wondering if there is a way to avoid the C short circuiting for
>> boolean expressions such as the following:
>>
>> if(a&&  b&&  c) {
>>       /* Do stuff */
>> }
>>
>> I am currently doing GPU programming and it would be better to evaluate
>> the entire condition, even if a is 0, since branches are slow.
>
> How does GPU programming relate to C programming?
>
> Sure, GLSL/HLSL/Cg are "C-like" languages, but they aren't C.
>
>


I'm using OpenCL's library which then invokes the GPU.  The programming 
is done in a subset of C.

--Bill

[toc] | [prev] | [next] | [standalone]


#4867

FromNobody <nobody@nowhere.com>
Date2011-05-27 07:41 +0100
Message-ID<pan.2011.05.27.06.41.10.672000@nowhere.com>
In reply to#4854
On Thu, 26 May 2011 21:34:24 -0400, Billy Mays wrote:

>> How does GPU programming relate to C programming?
>>
>> Sure, GLSL/HLSL/Cg are "C-like" languages, but they aren't C.
> 
> I'm using OpenCL's library which then invokes the GPU.  The programming 
> is done in a subset of C.

OpenCL may be closer to C than e.g. GLSL, but it still isn't C. And even
if it was, C doesn't define the execution time of any given construct, nor
treat it as significant (i.e. a compiler make whatever optimisations it
likes so long as the code produces the correct result, regardless of the
effect upon execution time).

AFAICT, the only reliable way to prevent short-circuting is to either
ensure that the later expressions have side-effects such that
short-circuiting would change the observable behaviour, or to "hide" their
implementation in a different translation unit so that the compiler cannot
determine whether short-circuiting will change the observable behaviour.

Either approach is likely to impose an unnecessary performance penalty on
either or both implementations (CPU and GPU). I don't know whether the
latter approach is even possible for OpenCL.

Actually, with modern CPUs performing speculative execution, I'm not sure
that the "hiding" approach will work. If the CPU hasn't performed the
calculation by the time it discovers that the result isn't needed, it
will just cancel it.

[toc] | [prev] | [next] | [standalone]


#4852

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2011-05-26 21:21 -0400
Message-ID<irmubh$si8$1@dont-email.me>
In reply to#4812
On 5/26/2011 1:58 PM, Billy Mays wrote:
> Hey CLC,
>
> I was wondering if there is a way to avoid the C short circuiting for
> boolean expressions such as the following:
>
> if(a && b && c) {
> /* Do stuff */
> }
>
> I am currently doing GPU programming and it would be better to evaluate
> the entire condition, even if a is 0, since branches are slow.

     You will take one branch if a or b or c is zero, none if all
are nonzero.  You will never take more than one branch.  So no
rearrangement can help unless a branch-not-taken has significant
cost.

     If it's still worth proceeding, consider replacing && with &:

	if (a & b & c) ...

This is not quite equivalent to the original, because it can only
work with integer operands and only then if a,b,c have suitable
values (consider 1,7,32, for example).  But you can fix that:

	if ((a != 0) & (b != 0) & (c != 0)) ...

or more briefly:

	if ( !(!a | !b | !c)) ...

or if you find that hard to read:

	if (!!a & !!b & !!c) ...

     Of course, the question of what all these alternatives compile
to and which is fastest in your particular situation is something
that you'll have to answer yourself, preferably by measurement.

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


#4856

FromShao Miller <sha0.miller@gmail.com>
Date2011-05-26 20:41 -0500
Message-ID<irmvh4$2an$1@dont-email.me>
In reply to#4812
On 5/26/2011 12:58 PM, Billy Mays wrote:
> Hey CLC,
>
> I was wondering if there is a way to avoid the C short circuiting for
> boolean expressions such as the following:
>
> if(a && b && c) {
> /* Do stuff */
> }
>
> I am currently doing GPU programming and it would be better to evaluate
> the entire condition, even if a is 0, since branches are slow.

   #include <stdio.h>

   #define f(x) ((x) ? 1 : 0)

   int main(void) {
       int a, b, c = b = a = 0;
       if (1 << 2 >> f(a) >> f(b) >> f(c))
         puts("Boo.");
         else
         puts("Yay.");
       return 0;
     }

[toc] | [prev] | [next] | [standalone]


#4858

FromShao Miller <sha0.miller@gmail.com>
Date2011-05-26 21:03 -0500
Message-ID<irn0pf$8i8$1@dont-email.me>
In reply to#4856
On 5/26/2011 8:41 PM, Shao Miller wrote:
> On 5/26/2011 12:58 PM, Billy Mays wrote:
>> Hey CLC,
>>
>> I was wondering if there is a way to avoid the C short circuiting for
>> boolean expressions such as the following:
>>
>> if(a && b && c) {
>> /* Do stuff */
>> }
>>
>> I am currently doing GPU programming and it would be better to evaluate
>> the entire condition, even if a is 0, since branches are slow.

Sorry, that was a bad example as GCC was clever and actually produced a 
branch.  So a better example might be:

   #include <stdio.h>

   #define f(x) ((x) ? 1 : 0)

   int main(void) {
       volatile int x = 1, a, b, c = b = a = 2;
       if (x << 2 >> f(a) >> f(b) >> f(c))
         puts("Boo.");
         else
         puts("Yay.");
       return 0;
     }

[toc] | [prev] | [next] | [standalone]


#4860

FromShao Miller <sha0.miller@gmail.com>
Date2011-05-26 21:37 -0500
Message-ID<irn2q0$ici$1@dont-email.me>
In reply to#4858
On 5/26/2011 9:03 PM, Shao Miller wrote:
> On 5/26/2011 8:41 PM, Shao Miller wrote:
>> On 5/26/2011 12:58 PM, Billy Mays wrote:
>>> Hey CLC,
>>>
>>> I was wondering if there is a way to avoid the C short circuiting for
>>> boolean expressions such as the following:
>>>
>>> if(a && b && c) {
>>> /* Do stuff */
>>> }
>>>
>>> I am currently doing GPU programming and it would be better to evaluate
>>> the entire condition, even if a is 0, since branches are slow.

Though the strategy'd grow pretty quickly, maybe even:

   #include <stdio.h>

   const char * func(int a, int b, int c) {
       static const char * const ret[] = {"Boo.", "Yay."};
       static const int table[2][2][2] = {{{0,0},{0,0}},{{0,0},{0,1}}};
       return table[!!a][!!b][!!c][ret];
     }

   int main(void) {
       puts(func(0, 0, 0));
       puts(func(0, 0, 3));
       puts(func(0, 5, 0));
       puts(func(0, 7, 11));
       puts(func(13, 0, 0));
       puts(func(17, 0, 1));
       puts(func(19, 23, 0));
       puts(func(29, 31, 37));
       return 0;
     }

[toc] | [prev] | [next] | [standalone]


#4880

FromImpalerCore <jadill33@gmail.com>
Date2011-05-27 09:01 -0700
Message-ID<5d853059-e0c5-4ef1-b758-f56a02355c22@p23g2000vbl.googlegroups.com>
In reply to#4812
On May 26, 1:58 pm, Billy Mays <no...@nohow.com> wrote:
> Hey CLC,
>
> I was wondering if there is a way to avoid the C short circuiting for
> boolean expressions such as the following:
>
> if(a && b && c) {
>      /* Do stuff */
>
> }
>
> I am currently doing GPU programming and it would be better to evaluate
> the entire condition, even if a is 0, since branches are slow.

Not sure if it would work, but what about evaluating the condition
outside of the 'if' statement?  It has the overhead of allocating an
additional variable.

bool my_condition_is_true = a && b && c;
if (my_condition_is_true) {
  /* Do stuff */
}

Best regards,
John D.

[toc] | [prev] | [next] | [standalone]


#4881

FromWillem <willem@toad.stack.nl>
Date2011-05-27 16:08 +0000
Message-ID<slrnitvj37.1ref.willem@toad.stack.nl>
In reply to#4880
ImpalerCore wrote:
) On May 26, 1:58?pm, Billy Mays <no...@nohow.com> wrote:
)> I was wondering if there is a way to avoid the C short circuiting for
)> boolean expressions such as the following:
)>
)> if(a && b && c) {
)> ? ? ?/* Do stuff */
)>
)> }
)>
)> I am currently doing GPU programming and it would be better to evaluate
)> the entire condition, even if a is 0, since branches are slow.
)
) Not sure if it would work, but what about evaluating the condition
) outside of the 'if' statement?
)
) bool my_condition_is_true = a && b && c;
) if (my_condition_is_true) {
)   /* Do stuff */
) }

Nope, that would make the exact same branches.
I wouldn't be surprised if it generated exactly the same opcodes, even.


SaSW, Willem
-- 
Disclaimer: I am in no way responsible for any of the statements
            made in the above text. For all I know I might be
            drugged or something..
            No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT

[toc] | [prev] | [next] | [standalone]


#4882

FromImpalerCore <jadill33@gmail.com>
Date2011-05-27 09:46 -0700
Message-ID<4564c84d-ae29-4546-81bd-95af628c4b5d@k17g2000vbn.googlegroups.com>
In reply to#4881
On May 27, 12:08 pm, Willem <wil...@toad.stack.nl> wrote:
> ImpalerCore wrote:
>
> ) On May 26, 1:58?pm, Billy Mays <no...@nohow.com> wrote:
> )> I was wondering if there is a way to avoid the C short circuiting for
> )> boolean expressions such as the following:
> )>
> )> if(a && b && c) {
> )> ? ? ?/* Do stuff */
> )>
> )> }
> )>
> )> I am currently doing GPU programming and it would be better to evaluate
> )> the entire condition, even if a is 0, since branches are slow.
> )
> ) Not sure if it would work, but what about evaluating the condition
> ) outside of the 'if' statement?
> )
> ) bool my_condition_is_true = a && b && c;
> ) if (my_condition_is_true) {
> )   /* Do stuff */
> ) }
>
> Nope, that would make the exact same branches.
> I wouldn't be surprised if it generated exactly the same opcodes, even.

Oh, I get it now.  The branches referred to are in the '&&' operator.
Thanks.

[toc] | [prev] | [next] | [standalone]


#4936

FromBGB <cr88192@hotmail.com>
Date2011-05-28 13:27 -0700
Message-ID<irrm1p$cp7$1@news.albasani.net>
In reply to#4882
On 5/27/2011 9:46 AM, ImpalerCore wrote:
> On May 27, 12:08 pm, Willem<wil...@toad.stack.nl>  wrote:
>> ImpalerCore wrote:
>>
>> ) On May 26, 1:58?pm, Billy Mays<no...@nohow.com>  wrote:
>> )>  I was wondering if there is a way to avoid the C short circuiting for
>> )>  boolean expressions such as the following:
>> )>
>> )>  if(a&&  b&&  c) {
>> )>  ? ? ?/* Do stuff */
>> )>
>> )>  }
>> )>
>> )>  I am currently doing GPU programming and it would be better to evaluate
>> )>  the entire condition, even if a is 0, since branches are slow.
>> )
>> ) Not sure if it would work, but what about evaluating the condition
>> ) outside of the 'if' statement?
>> )
>> ) bool my_condition_is_true = a&&  b&&  c;
>> ) if (my_condition_is_true) {
>> )   /* Do stuff */
>> ) }
>>
>> Nope, that would make the exact same branches.
>> I wouldn't be surprised if it generated exactly the same opcodes, even.
>
> Oh, I get it now.  The branches referred to are in the '&&' operator.
> Thanks.

hmm, maybe:
!((!a)|(!b)|(!c))

I don't know if any have mentioned this one.
reasoning: (!a) will reduce the value to 0/1, allowing plain bitwise 
operators; if any of a/b/c is false, the result of (!a)/(!b)/(!c) is 1 
(rather than 0), which will then be reversed by the final "!".


but, who knows which optimizations the GPU-specific compiler may have 
done?...

a compiler may well observe that if all of the operations are clean / 
non-destructive, then the as-if rule will allow optimizing away the 
short-circuit.

or, knowing about this, they may well have just "reinterpreted" the && 
and || operators for their particular target, since what they have isn't 
strictly C anyways, and so there is no particular need for them to 
follow pedantic interpretations of the standard either, for that matter.

[toc] | [prev] | [next] | [standalone]


#4908

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-05-28 09:44 -0400
Message-ID<irqu8p$8gg$2@dont-email.me>
In reply to#4812
On 05/26/2011 01:58 PM, Billy Mays wrote:
> Hey CLC,
> 
> I was wondering if there is a way to avoid the C short circuiting for 
> boolean expressions such as the following:
> 
> if(a && b && c) {
>      /* Do stuff */
> }
> 
> I am currently doing GPU programming and it would be better to evaluate 
> the entire condition, even if a is 0, since branches are slow.

I assume that, if you're willing to have the entire condition evaluated,
then neither b nor c represent expressions with side-effects. In
particular, neither of them is or involves the value of an object
defined with volatile.

Then there's two basic cases that need to be distinguished:
1. The compiler can figure out that neither b nor c are expressions with
side effects.
If this is the case, then any sufficiently good compiler targeting your
platform should generate code that evaluates both b and c, and then
discarding their values if not needed; at least, it should do so
whenever it makes sense to do so. This is allowed by the C standard,
even though it says explicitly that they should only be evaluated if
needed. That's because of the fact that they have no side-effects. As a
result, there's no way for a strictly conforming program to determine
whether or not the compiler is doing this, so the as-if rule allows the
compiler to do this.
If your compiler isn't smart enough to perform this optimization
automatically, there's no way in C to tell it explicitly to perform it.

2. The compiler cannot figure out that neither b nor c have side-effects.
About the only way this could be true is if one or both of those
expressions involve a function call. If all three expressions have
integral type, try:

        if(a & b & c)
	{
	}

The use of '&' rather than '&&' removes the short-circuiting behavior,
but the net result is the same, as long as integer types are involved.
If any of the expressions has a floating point or pointer type, you'll
have to insert !=0, and that will probably be converted into a branch,
which is precisely what you're trying to avoid.

-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#4921

FromKeith Thompson <kst-u@mib.org>
Date2011-05-28 12:15 -0700
Message-ID<lnhb8etz5r.fsf@nuthaus.mib.org>
In reply to#4908
James Kuyper <jameskuyper@verizon.net> writes:
[...]
> 2. The compiler cannot figure out that neither b nor c have side-effects.
> About the only way this could be true is if one or both of those
> expressions involve a function call. If all three expressions have
> integral type, try:
>
>         if(a & b & c)
> 	{
> 	}
>
> The use of '&' rather than '&&' removes the short-circuiting behavior,
> but the net result is the same, as long as integer types are involved.

And as long as they all have values of 0 or 1.

[...]

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#4940

FromJames Kuyper <jameskuyper@verizon.net>
Date2011-05-28 17:07 -0400
Message-ID<irro6k$dom$1@dont-email.me>
In reply to#4921
On 05/28/2011 03:15 PM, Keith Thompson wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
> [...]
>> 2. The compiler cannot figure out that neither b nor c have side-effects.
>> About the only way this could be true is if one or both of those
>> expressions involve a function call. If all three expressions have
>> integral type, try:
>>
>>         if(a & b & c)
>> 	{
>> 	}
>>
>> The use of '&' rather than '&&' removes the short-circuiting behavior,
>> but the net result is the same, as long as integer types are involved.
> 
> And as long as they all have values of 0 or 1.

Sorry, you're right. I was in rush when I wrote that, and I was thinking
of || and |, rather than && and &.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#4978

From"Herbert Rosenau" <os2guy@pc-rosenau.de>
Date2011-05-29 07:25 +0000
Message-ID<wmzsGguTDN6N-pn2-KiL4UMxnQpkx@JUPITER.PC-ROSENAU.DE>
In reply to#4812
On Thu, 26 May 2011 17:58:59 UTC, Billy Mays <noway@nohow.com> wrote:

> Hey CLC,
> 
> I was wondering if there is a way to avoid the C short circuiting for 
> boolean expressions such as the following:
> 
> if(a && b && c) {
>      /* Do stuff */
> }
> 
> I am currently doing GPU programming and it would be better to evaluate 
> the entire condition, even if a is 0, since branches are slow.
> 
if (!(a | b | c)) {
   /* do stuff on neither a, b and c are true */
} else {
   /* either a, b or c are false */
}

-- 
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 2.0 ist da!

[toc] | [prev] | [next] | [standalone]


#5133

Fromfalk@rahul.net (Edward A. Falk)
Date2011-05-31 18:40 +0000
Message-ID<is3cm4$cp1$2@blue.rahul.net>
In reply to#4812
In article <irm4et$66d$1@speranza.aioe.org>,
Billy Mays  <noway@nohow.com> wrote:
>Hey CLC,
>
>I was wondering if there is a way to avoid the C short circuiting for 
>boolean expressions such as the following:
>
>if(a && b && c) {
>     /* Do stuff */
>}
>
>I am currently doing GPU programming and it would be better to evaluate 
>the entire condition, even if a is 0, since branches are slow.

Unless a, b, and c are all simple register values, you'll have a hard
time convincing me that simple short branches are slower than evaluating
them.

-- 
	-Ed Falk, falk@despams.r.us.com
	http://thespamdiaries.blogspot.com/

[toc] | [prev] | [next] | [standalone]


#5287

FromBGB <cr88192@hotmail.com>
Date2011-06-02 09:48 -0700
Message-ID<is8f3k$r6a$1@news.albasani.net>
In reply to#5133
On 5/31/2011 11:40 AM, Edward A. Falk wrote:
> In article<irm4et$66d$1@speranza.aioe.org>,
> Billy Mays<noway@nohow.com>  wrote:
>> Hey CLC,
>>
>> I was wondering if there is a way to avoid the C short circuiting for
>> boolean expressions such as the following:
>>
>> if(a&&  b&&  c) {
>>      /* Do stuff */
>> }
>>
>> I am currently doing GPU programming and it would be better to evaluate
>> the entire condition, even if a is 0, since branches are slow.
>
> Unless a, b, and c are all simple register values, you'll have a hard
> time convincing me that simple short branches are slower than evaluating
> them.
>

actually, as far as performance is concerned, simple computations are 
faster than a (mispredicted) jump over them often even on plain x86 
(including with floating point, albeit with the partial exception of 
slow/complex operations like "sqrt()" or "sin()", or large/bulky 
calculations).

so, in my experience it is often a little faster just to do math which 
works over the entire range, rather than having to add conditionals into 
the mix.

granted, it depends some, as many algorithms are expressed better with 
conditionals, or need them, so it is not usually worthwhile to try to 
micro-optimize them out.


this situation also causes "switch()" when using a jump table to be a 
surprisingly expensive operation, which can matter somewhat when using a 
switch with a decent number of cases in a tight loop (for a small number 
of cases, compilers will often optimize this by using a slightly faster 
if-else chain internally, due mostly to branch-predictor magic...).


also, memory accesses are very fast when in-cache (almost as fast as 
with plain registers), and IME it means that having values in registers 
is not necessarily better performance-wise, since often trying to keep 
values in registers may lead to a larger total number of loads and 
stores (due to register spills, ...) so often it will make more sense to 
leave variables on-stack or similar.

IME, there has also been little difference performance with between 
simple and complex memory addresses, as apparently the processor 
calculates complex memory addresses more or less for free.

actually, the above also results in a possible optimization of 
calculating integer expressions like "x*4+y" using a "lea" instruction.


or such...

[toc] | [prev] | [next] | [standalone]


#5329

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2011-06-02 21:05 -0400
Message-ID<is9c33$kp9$1@dont-email.me>
In reply to#5287
On 6/2/2011 12:48 PM, BGB wrote:
> On 5/31/2011 11:40 AM, Edward A. Falk wrote:
>> In article<irm4et$66d$1@speranza.aioe.org>,
>> Billy Mays<noway@nohow.com> wrote:
>>> Hey CLC,
>>>
>>> I was wondering if there is a way to avoid the C short circuiting for
>>> boolean expressions such as the following:
>>>
>>> if(a&& b&& c) {
>>> /* Do stuff */
>>> }
>>>
>>> I am currently doing GPU programming and it would be better to evaluate
>>> the entire condition, even if a is 0, since branches are slow.
>>
>> Unless a, b, and c are all simple register values, you'll have a hard
>> time convincing me that simple short branches are slower than evaluating
>> them.
>
> actually, as far as performance is concerned, simple computations are
> faster than a (mispredicted) jump over them often even on plain x86
> (including with floating point, albeit with the partial exception of
> slow/complex operations like "sqrt()" or "sin()", or large/bulky
> calculations).

     In a purely sequential model, only the accuracy of the branch
prediction will make any difference.  Either way you write the code,
you will take exactly one branch if there's an `else', zero or one
branches if not.  You'll take the same number of branches with `&&'
as with `&' or a variant; the only difference is in how many branches
you'll execute but not take.  If they're usually not taken but usually
predicted to be taken, all I can say is your compiler doesn't predict
very well and should get a job doing weather forecasts.

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

[toc] | [prev] | [standalone]


Page 3 of 3 — ← Prev page 1 2 [3]

Back to top | Article view | comp.lang.c


csiph-web