[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

Short-circuiting in C

Carl

5/26/2011 5:59:00 PM

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.

--
Bill Mays
64 Answers

Ben Pfaff

5/26/2011 6:10:00 PM

0

Billy Mays <noway@nohow.com> writes:

> 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 */
> }

x = a;
y = b;
z = c;
if (x && y && z) {
/* Do stuff */
}
--
Ben Pfaff
http://be...

ram

5/26/2011 6:17:00 PM

0

Billy Mays <noway@nohow.com> writes:
>I was wondering if there is a way to avoid the C short
>circuiting for boolean expressions such as the following:

In C, there are no »boolean expressions«. The conditional
evaluation is related to certain operators, not to the
programming language. The following is a statement.

>if(a && b && c) {
> /* Do stuff */
>}

What about

!!a & !!b & !!c

?

Thomas Richter

5/26/2011 6:22:00 PM

0

On 26.05.2011 20:09, Ben Pfaff wrote:
> Billy Mays<noway@nohow.com> writes:
>
>> 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 */
>> }
>
> x = a;
> y = b;
> z = c;
> if (x&& y&& z) {
> /* Do stuff */
> }

Sorry, I fail to see how this should work. Actually, a sufficiently
smart compiler would reduce this to just the above, and in fact, a
compiler can modify the code always on the basis of the "as-if" rule.

So the question goes back to the OP what the intent of disabling the
short-circuiting is. If it is to avoid two branches, then if a,b and c
are always 0 or 1 (or any other number, identical for all three
variables), you could simply write:

if (a & b & c) {
}

If the intent is that an actual access of the variables happen, probably
because they are hardware registers, then you would also suggest to
declare them as volatile.

However, typically the impact of such micro-optimizations is negligible.
Question to the OP: Did you actually measure?

Greetings,
Thomas

Ben Pfaff

5/26/2011 6:35:00 PM

0

Thomas Richter <thor@math.tu-berlin.de> writes:

> On 26.05.2011 20:09, Ben Pfaff wrote:
>> Billy Mays<noway@nohow.com> writes:
>>
>>> 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 */
>>> }
>>
>> x = a;
>> y = b;
>> z = c;
>> if (x&& y&& z) {
>> /* Do stuff */
>> }
>
> Sorry, I fail to see how this should work. Actually, a sufficiently
> smart compiler would reduce this to just the above, and in fact, a
> compiler can modify the code always on the basis of the "as-if" rule.

The code that I presented always evaluates all of 'a', 'b', and
'c', which is what the OP said that he wanted.
--
Ben Pfaff
http://be...

Morris Keesan

5/26/2011 6:36:00 PM

0

On Thu, 26 May 2011 14:17:15 -0400, Stefan Ram <ram@zedat.fu-berlin.de>
wrote:

> Billy Mays <noway@nohow.com> writes:
>> I was wondering if there is a way to avoid the C short
>> circuiting for boolean expressions such as the following:
>
> In C, there are no »boolean expressions«. The conditional
> evaluation is related to certain operators, not to the
> programming language. The following is a statement.
>
>> if(a && b && c) {
>> /* Do stuff */
>> }
>
> What about
>
> !!a & !!b & !!c

I find it easier to read as

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

The meaning of (a != 0) is more immediately obvious to me than !!a, which
I have to think about for a couple of seconds.

--
Morris Keesan -- mkeesan@post.harvard.edu

Scott Fluhrer

5/26/2011 6:39:00 PM

0


"Stefan Ram" <ram@zedat.fu-berlin.de> wrote in message
news:boolan-20110526201538@ram.dialup.fu-berlin.de...
> Billy Mays <noway@nohow.com> writes:
>>I was wondering if there is a way to avoid the C short
>>circuiting for boolean expressions such as the following:
>
> In C, there are no »boolean expressions«. The conditional
> evaluation is related to certain operators, not to the
> programming language. The following is a statement.
>
>>if(a && b && c) {
>> /* Do stuff */
>>}
>
> What about
>
> !!a & !!b & !!c
>
> ?

On some compilers, the expression !!x causes the compiler to emit a
conditional jump; on others it doesn't. The OP would be wise to test this
on his platform.

On the other hand, if the OP knows that a, b, c will be limited to the
values (0, 1), we have this code:

if (a & b & c) {
/* Do stuff */
}

--
poncho


ram

5/26/2011 6:40:00 PM

0

"Morris Keesan" <mkeesan@post.harvard.edu> writes:
>The meaning of (a != 0) is more immediately obvious to me than !!a, which
>I have to think about for a couple of seconds.

»!!« is a C idiom.

Carl

5/26/2011 6:51:00 PM

0

On 05/26/2011 02:22 PM, Thomas Richter wrote:
> On 26.05.2011 20:09, Ben Pfaff wrote:
>> Billy Mays<noway@nohow.com> writes:
>>
>>> 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 */
>>> }
>>
>> x = a;
>> y = b;
>> z = c;
>> if (x&& y&& z) {
>> /* Do stuff */
>> }
>
> Sorry, I fail to see how this should work. Actually, a sufficiently
> smart compiler would reduce this to just the above, and in fact, a
> compiler can modify the code always on the basis of the "as-if" rule.
>
> So the question goes back to the OP what the intent of disabling the
> short-circuiting is. If it is to avoid two branches, then if a,b and c
> are always 0 or 1 (or any other number, identical for all three
> variables), you could simply write:
>
> if (a & b & c) {
> }
>
> If the intent is that an actual access of the variables happen, probably
> because they are hardware registers, then you would also suggest to
> declare them as volatile.
>
> However, typically the impact of such micro-optimizations is negligible.
> Question to the OP: Did you actually measure?
>
> Greetings,
> Thomas


I did not, but I suspect using an & instead of an && would fail if a was
1 and b was 2. The programming guide I was using mentioned that the
short-circuiting behavior would force all the threads to serialize
rather than run in lockstep.

--
Bill

ram

5/26/2011 7:03:00 PM

0

Billy Mays <noway@nohow.com> writes:
>I did not, but I suspect using an & instead of an && would fail if a was
>1 and b was 2. The programming guide I was using mentioned that the
>short-circuiting behavior would force all the threads to serialize
>rather than run in lockstep.

Which threads?

BTW, I forgot to mention that there is another difference
between »&&« and »&«: »&« has no sequence-point, so when you
need a certain sequence, you can't rely on »&«.

Carl

5/26/2011 7:10:00 PM

0

On 05/26/2011 03:03 PM, Stefan Ram wrote:
> Billy Mays<noway@nohow.com> writes:
>> I did not, but I suspect using an& instead of an&& would fail if a was
>> 1 and b was 2. The programming guide I was using mentioned that the
>> short-circuiting behavior would force all the threads to serialize
>> rather than run in lockstep.
>
> Which threads?
>
> BTW, I forgot to mention that there is another difference
> between »&&« and »&«: »&« has no sequence-point, so when you
> need a certain sequence, you can't rely on »&«.
>

On the GPU I am using, threads execute simultaneously as long as they
all execute the exact same instructions (ie, they all take the branch).
If one of the threads takes a different execution path, then each
thread has to run in serial which means the parallel speed gain is lost.

It would be cheaper to evaluate the whole expression rather than
short-circuit since it would mean that all the threads could take the
same path.

For example,

if(a && b && c) {
/* Do stuff */
}

Thread 1: a = 1, b = 2, c = 0

Thread 2: a = 0, b = 1, c = 2

Neither thread will execute the body of the if statement, but Thread 2
would branch away while Thread 1 would still be evaluating b and c.

--
Bill