Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Short-circuiting in C (http://www.velocityreviews.com/forums/t749011-short-circuiting-in-c.html)

 Billy Mays 05-26-2011 05:58 PM

Short-circuiting in C

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

 Ben Pfaff 05-26-2011 06:09 PM

Re: Short-circuiting in C

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://benpfaff.org

 Stefan Ram 05-26-2011 06:17 PM

Re: Short-circuiting in C

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

!!a & !!b & !!c

?

 Thomas Richter 05-26-2011 06:22 PM

Re: Short-circuiting in C

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 05-26-2011 06:35 PM

Re: Short-circuiting in C

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://benpfaff.org

 Morris Keesan 05-26-2011 06:36 PM

Re: Short-circuiting in C

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

>
>
> !!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

 Stefan Ram 05-26-2011 06:40 PM

Re: Short-circuiting in C

"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.

 Billy Mays 05-26-2011 06:51 PM

Re: Short-circuiting in C

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

 Stefan Ram 05-26-2011 07:03 PM

Re: Short-circuiting in C

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.

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 »&«.

 Billy Mays 05-26-2011 07:10 PM

Re: Short-circuiting in C

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.

>
>
> 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

All times are GMT. The time now is 02:10 PM.