Velocity Reviews > Short-circuiting in C

# Short-circuiting in C

Billy Mays
Guest
Posts: n/a

 05-26-2011
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
Guest
Posts: n/a

 05-26-2011
Billy Mays <(E-Mail Removed)> 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
Guest
Posts: n/a

 05-26-2011
Billy Mays <(E-Mail Removed)> 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
Guest
Posts: n/a

 05-26-2011
On 26.05.2011 20:09, Ben Pfaff wrote:
> Billy Mays<(E-Mail Removed)> 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
Guest
Posts: n/a

 05-26-2011
Thomas Richter <(E-Mail Removed)-berlin.de> writes:

> On 26.05.2011 20:09, Ben Pfaff wrote:
>> Billy Mays<(E-Mail Removed)> 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
Guest
Posts: n/a

 05-26-2011
On Thu, 26 May 2011 14:17:15 -0400, Stefan Ram <(E-Mail Removed)-berlin.de>
wrote:

> Billy Mays <(E-Mail Removed)> 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 -- http://www.velocityreviews.com/forums/(E-Mail Removed)

Stefan Ram
Guest
Posts: n/a

 05-26-2011
"Morris Keesan" <(E-Mail Removed)> 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
Guest
Posts: n/a

 05-26-2011
On 05/26/2011 02:22 PM, Thomas Richter wrote:
> On 26.05.2011 20:09, Ben Pfaff wrote:
>> Billy Mays<(E-Mail Removed)> 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
Guest
Posts: n/a

 05-26-2011
Billy Mays <(E-Mail Removed)> 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
Guest
Posts: n/a

 05-26-2011
On 05/26/2011 03:03 PM, Stefan Ram wrote:
> Billy Mays<(E-Mail Removed)> 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