468,771 Members | 1,939 Online

# lshift & rshift

Hello guys,
every time a rode a doc or a book about the language C I saw that
operators << and >exist. But each time they said that << translate
the digit to the left (and >...) but no one said if a << 1 mean
every time a * 2, because there is the problem with the way the
integer are stored. So I never use thoses operators because I fear
strange behaviour on different architecture. Can I use them and be
sure that a << 1 means a * 2 on every computer ? Is is in the ansi
standard of language C ?

Sep 27 '07 #1
71 3736
ie***@free.fr said:
Hello guys,
every time a rode a doc or a book about the language C I saw that
operators << and >exist. But each time they said that << translate
the digit
Each bit is moved one place to the left, the leftmost bit falls off the end
into the bit bucket (which should be emptied regularly), and the rightmost
bit is set to 0.
to the left (and >...)
Beware signed types when shifting. The danger is particularly - er -
dangerous when right-shifting negative numbers. What happens to the sign
bit? (Answer: it depends on the implementation.)
but no one said if a << 1 mean
every time a * 2,
Not every time, no. For example, consider a system where CHAR_BIT is 8.

unsigned char ch = 1;

ch <<= 1; /* ch is now 2 */
ch <<= 1; /* ch is now 4 */
ch <<= 1; /* ch is now 8 */
ch <<= 1; /* ch is now 16 */
ch <<= 1; /* ch is now 32 */
ch <<= 1; /* ch is now 64 */
ch <<= 1; /* ch is now 128 */
ch <<= 1; /* ch is now 0, even though 2 * 128 is 256. */
because there is the problem with the way the
integer are stored. So I never use thoses operators because I fear
strange behaviour on different architecture. Can I use them and be
sure that a << 1 means a * 2 on every computer ?
If you stick to unsigned types, and don't push any 1-bits off the end, yes.
But why bother? Why not just multiply by 2, if that's what you want to do?
Is is in the ansi standard of language C ?
Yes, but - like I said - you do need to be careful.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sep 27 '07 #2
ie***@free.fr wrote:
Hello guys,
every time a rode a doc or a book about the language C I saw that
operators << and >exist. But each time they said that << translate
the digit to the left (and >...) but no one said if a << 1 mean
every time a * 2, because there is the problem with the way the
integer are stored. So I never use thoses operators because I fear
strange behaviour on different architecture. Can I use them and be
sure that a << 1 means a * 2 on every computer ? Is is in the ansi
standard of language C ?
One of the problems with using the bit-shift operators to do arithmetic is you
no longer say what you mean. If you want to multiply something by 2, say so.

Another problem is that bit-shifting is not entirely defined for signed types.
This is partly because a bit-shift could move a value bit into a sign bit, or
vice versa, and partly because C allows different representations of signed
integers (2's complement, 1's complement, or sign-magnitude).

In the bad old days, some people used to use bit-shifts to perform simple
multiplications because it would run quicker. These days, compilers can spot for
themselves when this sort of trick is possible and will do so.

For arithmetic, use arithmetic operators. Save bit-shifting for when you need
bit-shifting semantics - for example, simulating a shift register.

--
Philip Potter pgp <atdoc.ic.ac.uk
Sep 27 '07 #3
In the bad old days, some people used to use bit-shifts to perform simple
multiplications because it would run quicker. These days, compilers can spot for
themselves when this sort of trick is possible and will do so.

For arithmetic, use arithmetic operators. Save bit-shifting for when you need
bit-shifting semantics - for example, simulating a shift register.

--
Philip Potter pgp <atdoc.ic.ac.uk
So if I want to multiply an int by two I have to use a * 2 (or a + a),
but not << ? To be sure it works on every architecture (currently I
ignore the problem of the size of an int).

Sep 27 '07 #4
ie***@free.fr wrote:
So if I want to multiply an int by two I have to use a * 2 <snip>?
Why would you want to do it any other way?
Sep 27 '07 #5
On Sep 27, 10:56 am, Mark Bluemel <mark_blue...@pobox.comwrote:
ie...@free.fr wrote:
So if I want to multiply an int by two I have to use a * 2 <snip>?

Why would you want to do it any other way?
If << is faster, it would be great. I love to have fast software, I'm
not rich and don't buy expensive computer.

Sep 27 '07 #6
ie***@free.fr wrote:
On Sep 27, 10:56 am, Mark Bluemel <mark_blue...@pobox.comwrote:
>ie...@free.fr wrote:
>>So if I want to multiply an int by two I have to use a * 2 <snip>?
Why would you want to do it any other way?

If << is faster, it would be great. I love to have fast software, I'm
not rich and don't buy expensive computer.
What did your profiler tell you?

--
Ian Collins.
Sep 27 '07 #7
On Sep 27, 2:10 pm, "ie...@free.fr" <ie...@free.frwrote:
On Sep 27, 10:56 am, Mark Bluemel <mark_blue...@pobox.comwrote:
ie...@free.fr wrote:
So if I want to multiply an int by two I have to use a * 2 <snip>?
Why would you want to do it any other way?

If << is faster, it would be great. I love to have fast software, I'm
not rich and don't buy expensive computer.
Did you try to view the assembly of a * 2 or the assembly of a + a .
I think,a*2 and a+a must internally be doing shifting using the shift
operators if shift operators are very fast.
Am i right ?

If thatz wrong then, How do you think, a*2 or a+a will be internally ?

Karthik Balaguru

Sep 27 '07 #8
ie***@free.fr wrote:
On Sep 27, 10:56 am, Mark Bluemel <mark_blue...@pobox.comwrote:
>ie...@free.fr wrote:
>>So if I want to multiply an int by two I have to use a * 2 <snip>?
Why would you want to do it any other way?

If << is faster, it would be great. I love to have fast software, I'm
not rich and don't buy expensive computer.
As others have already pointed out, the compiler will be more than
capable of applying this sort of optimisation if it is appropriate. In
general you should write clear, correct, expressive code and let the
compiler deal with optimisation. Any decent compiler is likely to do a
better job of optimising this sort of thing than you could.

If you have performance issues, you are generally better off looking for
better algorithms than fiddling with this sort of trivia.

If you have to get down to tuning at the code, rather than algorithm,
level then you need to profile your code as Ian has suggested. Only by
measuring will you find the bottlenecks.
Sep 27 '07 #9
Did you try to view the assembly of a * 2 or the assembly of a + a .
I think,a*2 and a+a must internally be doing shifting using the shift
operators if shift operators are very fast.
Am i right ?
No you're wrong. A saw that it change a * 2 by a + a. (in reality I
was looking at a * 7) and I saw something like that :
b = a + a
c = b + b
c + b + a
So after I try a * 2 and get
a + a
But it didn't use lshift.

Sep 27 '07 #10
What did your profiler tell you?

What is a profiler ?

Sep 27 '07 #11
ie***@free.fr wrote:
>What did your profiler tell you?

What is a profiler ?
A very useful tool that's included in any self respecting tool set.

http://en.wikipedia.org/wiki/Performance_analysis

--
Ian Collins.
Sep 27 '07 #12
On Sep 27, 11:28 am, Ian Collins <ian-n...@hotmail.comwrote:
ie...@free.fr wrote:
What did your profiler tell you?
What is a profiler ?

A very useful tool that's included in any self respecting tool set.

http://en.wikipedia.org/wiki/Performance_analysis

--
Ian Collins.
I never use these kind of stuffs.

Sep 27 '07 #13
ie***@free.fr wrote:
On Sep 27, 11:28 am, Ian Collins <ian-n...@hotmail.comwrote:
>ie...@free.fr wrote:
>>>What did your profiler tell you?
What is a profiler ?
A very useful tool that's included in any self respecting tool set.

http://en.wikipedia.org/wiki/Performance_analysis

I never use these kind of stuffs.
Then you shouldn't be fiddling with micro-optimisations.

--
Ian Collins.
Sep 27 '07 #14
Richard Heathfield wrote:
>
ie***@free.fr said:
Hello guys,
every time a rode a doc or a book about the language C I saw that
operators << and >exist. But each time they said that << translate
the digit

Each bit is moved one place to the left,
the leftmost bit falls off the end
into the bit bucket (which should be emptied regularly),
and the rightmost bit is set to 0.
to the left (and >...)

Beware signed types when shifting. The danger is particularly - er -
dangerous when right-shifting negative numbers.
What happens to the sign bit?
(Answer: it depends on the implementation.)
but no one said if a << 1 mean
every time a * 2,

Not every time, no.
For example, consider a system where CHAR_BIT is 8.

unsigned char ch = 1;

ch <<= 1; /* ch is now 2 */
ch <<= 1; /* ch is now 4 */
ch <<= 1; /* ch is now 8 */
ch <<= 1; /* ch is now 16 */
ch <<= 1; /* ch is now 32 */
ch <<= 1; /* ch is now 64 */
ch <<= 1; /* ch is now 128 */
ch <<= 1; /* ch is now 0, even though 2 * 128 is 256. */
That example doesn't show a difference
between shifting and a doubling.

The result of each shift
is the same as what you would get from multiplication.

CHAR_BIT is 8

unsigned char ch = 1;

ch *= 2; /* ch is now 2 */
ch *= 2; /* ch is now 4 */
ch *= 2; /* ch is now 8 */
ch *= 2; /* ch is now 16 */
ch *= 2; /* ch is now 32 */
ch *= 2; /* ch is now 64 */
ch *= 2; /* ch is now 128 */
ch *= 2; /* ch is now 0, even though 2 * 128 is 256. */

--
pete
Sep 27 '07 #15
Then you shouldn't be fiddling with micro-optimisations.

What ? I used to profile with my hands (like I debug with my hands).
And when a micro operation is used many times it becomes a macro
optimisations. Yeah generally I don't care about a * 2 or a + a. But
sometimes I need to use that 1000..... times so I need to know which
is fastest.

Sep 27 '07 #16
ie***@free.fr wrote:
>Then you shouldn't be fiddling with micro-optimisations.

What ? I used to profile with my hands (like I debug with my hands).
And when a micro operation is used many times it becomes a macro
optimisations. Yeah generally I don't care about a * 2 or a + a. But
sometimes I need to use that 1000..... times so I need to know which
is fastest.
Which is where a profiler comes in...
Sep 27 '07 #17
ie***@free.fr wrote:
>Then you shouldn't be fiddling with micro-optimisations.

What ? I used to profile with my hands (like I debug with my hands).
And when a micro operation is used many times it becomes a macro
optimisations. Yeah generally I don't care about a * 2 or a + a. But
sometimes I need to use that 1000..... times so I need to know which
is fastest.
That's what a profiler is there to help you do. It may also tell you
that there is a bigger bottleneck elsewhere.

--
Ian Collins.
Sep 27 '07 #18
"ie***@free.fr" <ie***@free.frwrote:
In the bad old days, some people used to use bit-shifts to perform simple
multiplications because it would run quicker. These days, compilers can spot for
themselves when this sort of trick is possible and will do so.

For arithmetic, use arithmetic operators. Save bit-shifting for when you need
bit-shifting semantics - for example, simulating a shift register.

So if I want to multiply an int by two I have to use a * 2 (or a + a),
but not << ?
No, if you want to multiply an int by two you use a*2. a+a is, like
a<<1, a micro-optimisation which in these days of good optimisers is
more likely to do harm than good. Make your code readable, and save the
tricks for when you have already proved you need them, not for when you
only think so.
To be sure it works on every architecture
To be sure, it does not. It may work on every architecture you know, but
that doesn't necessarily mean much if you've mainly worked with desktop
computers.

Shifting an unsigned integer always works, as long as your shift factor
is not negative or larger than the first operand's size.
Shifting a signed integer right works, but if it's negative, the result
is implementation-defined (i.e., it's not allowed to crash, but the
Standard doesn't demand any specific numeric result, it only requires
that the result _is_ a number and not a bus error; there are two
reasonable results, and I would expect to get either of these, but the
Standard doesn't even require this.) If the integer is positive, the
result is what you would expect.
Shifting a signed integer left only works if the expected result fits in
that integer type (in which case, it's required to be the actual
result). If the expected result would not fit, the result in this case
is undefined. This is worse than the previous case, because it means
that left-shifting a signed integer which is too large _can_ crash your
program.

Summary: only use bit-shifting if what you want to do _is_ bit-shifting,
and not if you want a "faster" multiplication or division, because that
may be counter-productive. Only use bit-shifting on signed integers if
you are sure of what you're doing. By preference, only use bit-shifting
on unsigned integers. It makes more sense for them, anyway.

Richard
Sep 27 '07 #19
Which is where a profiler comes in...

No. I know when I programm if * 2 will be used 10 times or 10000....
I know from the beginning where are the important and no important
part. I don't need a software to say me these kind of things, moreover
there are more dumbs than me (a computer beat myself, ha ha ha).

Sep 27 '07 #20
On Sep 27, 2:23 pm, "ie...@free.fr" <ie...@free.frwrote:
Did you try to view the assembly of a * 2 or the assembly of a + a .
I think,a*2 and a+a must internally be doing shifting using the shift
operators if shift operators are very fast.
Am i right ?

No you're wrong. A saw that it change a * 2 by a + a. (in reality I
was looking at a * 7) and I saw something like that :
b = a + a
c = b + b
c + b + a
So after I try a * 2 and get
a + a
But it didn't use lshift.
Can you post the snapshot of the internal of a*2 and a+a that you
got ?

Karthik Balaguru

Sep 27 '07 #21
On Sep 27, 4:47 am, "ie...@free.fr" <ie...@free.frwrote:
Which is where a profiler comes in...

No. I know when I programm if * 2 will be used 10 times or 10000....
I know from the beginning where are the important and no important
part. I don't need a software to say me these kind of things, moreover
there are more dumbs than me (a computer beat myself, ha ha ha).

It's been demonstrated repeatedly over the last few decades that
programmers are absolutely *terrible* at identifying hotspots in their
code. Sure, some easy cases are easy to spot, but others are not, and
it's very, very easy to spend a lot of time optimizing a piece of code
(and making it vastly less maintainable in the process) that isn't
actually a hotspot. Profiling will tell you the truth. Nor are all
these possible optimizations consistently beneficial, and often depend
on the implementation of the processor, so you must always measure

Sep 27 '07 #22
Can you post the snapshot of the internal of a*2 and a+a that you
got ?
I can't, it was in past. But I'm sure. I asked a friend, and he
explain me that on some architecture (like the HP adding machine)
there wasn't a multiplication in the CPU, so the multiplication was a
software and it was better to use + than *. And it was not a lshift, I
swear it.

Sep 27 '07 #23
It's been demonstrated repeatedly over the last few decades that
programmers are absolutely *terrible* at identifying hotspots in their
code.
Like they're terrible to produce a correct code.

Sep 27 '07 #24
<ie***@free.frschrieb im Newsbeitrag
>Can you post the snapshot of the internal of a*2 and a+a that you
got ?

I can't, it was in past. But I'm sure. I asked a friend, and he
explain me that on some architecture (like the HP adding machine)
there wasn't a multiplication in the CPU, so the multiplication was a
software and it was better to use + than *. And it was not a lshift, I
swear it.
Look at the machine/assembly code that get's generated _now_ on _your
platform_ and compare the code it generated for

a+a
a*2
a<<1

Repeat the comparision with the various optimization levels your compiler
provides.
Then lookup the the processors assembly manual and count CPU cycles.

Bye, Jojo
Sep 27 '07 #25
On Sep 27, 12:15 pm, "ie...@free.fr" <ie...@free.frwrote:
Can you post the snapshot of the internal of a*2 and a+a that you
got ?

I can't, it was in past. But I'm sure. I asked a friend, and he
explain me that on some architecture (like the HP adding machine)
there wasn't a multiplication in the CPU, so the multiplication was a
software and it was better to use + than *. And it was not a lshift, I
swear it.
Finnaly I can, here you are :
I made gcc -S mult.c to get the assembly code.

****mult.c****
**************
int mult_by_7 (int a)
{
return a * 7;
}

int mult_by_2 (int a)
{
return a * 2;
}

****mult.s****
**************
.file "mult.c"
.text
..globl mult_by_7
.type mult_by_7, @function
mult_by_7:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx
movl %edx, %eax
sall \$3, %eax
subl %edx, %eax
popl %ebp
ret
.size mult_by_7, .-mult_by_7
..globl mult_by_2
.type mult_by_2, @function
mult_by_2:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
popl %ebp
ret
.size mult_by_2, .-mult_by_2
.ident "GCC: (GNU) 4.1.2 (Ubuntu 4.1.2-0ubuntu4)"
.section .note.GNU-stack,"",@progbits

I don't understand the first (assembly language is a little bit new
for me).
Bu for mult_by_2 you can see the addl %eax,%eax
so it changed a * 2 by a + A.

Or perhaps I don't understand what does this assembly code.

Sep 27 '07 #26
I also try a << 1
and it converted it into a + a

Sep 27 '07 #27
<ie***@free.frschrieb im Newsbeitrag
On Sep 27, 12:15 pm, "ie...@free.fr" <ie...@free.frwrote:
Can you post the snapshot of the internal of a*2 and a+a that you
got ?

I can't, it was in past. But I'm sure. I asked a friend, and he
explain me that on some architecture (like the HP adding machine)
there wasn't a multiplication in the CPU, so the multiplication was a
software and it was better to use + than *. And it was not a lshift, I
swear it.

Finnaly I can, here you are :
I made gcc -S mult.c to get the assembly code.

****mult.c****
**************
int mult_by_7 (int a)
{
return a * 7;
}

int mult_by_2 (int a)
{
return a * 2;
}

****mult.s****
**************
.file "mult.c"
.text
.globl mult_by_7
.type mult_by_7, @function
mult_by_7:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx
movl %edx, %eax
sall \$3, %eax
subl %edx, %eax
popl %ebp
ret
.size mult_by_7, .-mult_by_7
.globl mult_by_2
.type mult_by_2, @function
mult_by_2:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
popl %ebp
ret
.size mult_by_2, .-mult_by_2
.ident "GCC: (GNU) 4.1.2 (Ubuntu 4.1.2-0ubuntu4)"
.section .note.GNU-stack,"",@progbits

I don't understand the first (assembly language is a little bit new
for me).
Bu for mult_by_2 you can see the addl %eax,%eax
so it changed a * 2 by a + A.
Looks like it. The other one looks likes a "a<<3 - a" to me, but that's only
a guess...
Now compare with the code for a shift_by_one.
Then switch on compiler optimization and check again.

Bye, Jojo
Sep 27 '07 #28
<ie***@free.frschrieb im Newsbeitrag
>I also try a << 1
and it converted it into a + a
Exactly our point here. So coding a*2 has no performance advantage over a<<1

Bye, Jojo
Sep 27 '07 #29
ie***@free.fr <ie***@free.frwrote:
>Then you shouldn't be fiddling with micro-optimisations.
>What ? I used to profile with my hands (like I debug with my hands).
And when a micro operation is used many times it becomes a macro
optimisations.
You are misunderstanding the term. Micro-optimisation doesn't mean
optimisation that has a very small effect, it means optimisation of
small operations, as opposed to optimisation of the algorithm.

Micro-optimisation can have have very large effects, but compilers are
generally better at it than humans.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Sep 27 '07 #30
On Sep 27, 5:23 am, "ie...@free.fr" <ie...@free.frwrote:
On Sep 27, 12:15 pm, "ie...@free.fr" <ie...@free.frwrote:
Can you post the snapshot of the internal of a*2 and a+a that you
got ?
I can't, it was in past. But I'm sure. I asked a friend, and he
explain me that on some architecture (like the HP adding machine)
there wasn't a multiplication in the CPU, so the multiplication was a
software and it was better to use + than *. And it was not a lshift, I
swear it.

Finnaly I can, here you are :
I made gcc -S mult.c to get the assembly code.

****mult.c****
**************
int mult_by_7 (int a)
{
return a * 7;

}

int mult_by_2 (int a)
{
return a * 2;

}

****mult.s****
**************
.file "mult.c"
.text
.globl mult_by_7
.type mult_by_7, @function
mult_by_7:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx
movl %edx, %eax
sall \$3, %eax
subl %edx, %eax
popl %ebp
ret
.size mult_by_7, .-mult_by_7
.globl mult_by_2
.type mult_by_2, @function
mult_by_2:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
popl %ebp
ret
.size mult_by_2, .-mult_by_2
.ident "GCC: (GNU) 4.1.2 (Ubuntu 4.1.2-0ubuntu4)"
.section .note.GNU-stack,"",@progbits

I don't understand the first (assembly language is a little bit new
for me).
Bu for mult_by_2 you can see the addl %eax,%eax
so it changed a * 2 by a + A.

Or perhaps I don't understand what does this assembly code.

The first routine compiles the (a*7) to ((a*8-a), with the
multiplication by eight done via a shift. In any event it looks like
you have not, as suggested, turned up the optimization level for GCC,
so he's generated fairly lame code. Try it with -O2 and see if that
doesn't reduce to a mov/lea/sub/ret sequence.

Sep 27 '07 #31
On Thu, 27 Sep 2007 01:26:53 -0700, ie***@free.fr wrote:
Hello guys,
every time a rode a doc or a book about the language C I saw that
operators << and >exist. But each time they said that << translate
the digit to the left (and >...) but no one said if a << 1 mean
every time a * 2, because there is the problem with the way the
integer are stored. So I never use thoses operators because I fear
strange behaviour on different architecture. Can I use them and be
sure that a << 1 means a * 2 on every computer ? Is is in the ansi
standard of language C ?
If the first operand is positive, it is.

--
Army1987 (Replace "NOSPAM" with "email")
A hamburger is better than nothing.
Nothing is better than eternal happiness.
Therefore, a hamburger is better than eternal happiness.

Sep 27 '07 #32
Looks like it. The other one looks likes a "a<<3 - a" to me, but that's only
a guess...
No you're right. It's just I'm not able to read assembly code.
I can't understand the result of my test. Maybe you're right.
I don't know.

Sep 27 '07 #33
On Sep 27, 5:16 am, "ie...@free.fr" <ie...@free.frwrote:
It's been demonstrated repeatedly over the last few decades that
programmers are absolutely *terrible* at identifying hotspots in their
code.

Like they're terrible to produce a correct code.

Indeed. And please be sure to remember to include yourself in that
category.

Sep 27 '07 #34
pete said:
Richard Heathfield wrote:
>>
<snip>
>ch <<= 1; /* ch is now 128 */
ch <<= 1; /* ch is now 0, even though 2 * 128 is 256. */

That example doesn't show a difference
between shifting and a doubling.
I agree. It does, however, show that shifting doesn't always double the
number. The fact that doubling doesn't always double the number is another
issue. :-)

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sep 27 '07 #35
"ie***@free.fr" <ie***@free.frwrote:
Which is where a profiler comes in...

No. I know when I programm if * 2 will be used 10 times or 10000....
I know from the beginning where are the important and no important
part. I don't need a software to say me these kind of things, moreover
there are more dumbs than me (a computer beat myself, ha ha ha).
You overestimate yourself. That's ok; nearly everybody does, until he
gets a taste of what a _real_ profiler and debugging suite can do. But
it isn't wise to refuse to learn better.

Richard
Sep 27 '07 #36
On Sep 27, 3:30 pm, "ie...@free.fr" <ie...@free.frwrote:
I also try a << 1
and it converted it into a + a
What is the optimisation level you have ?
Does it treat a<<1 and a*2 as a+a for all the optimisation levels ?
What is the architecture you use ?

It is dependent on your architecture and compiler you use.

Karthik Balaguru

Sep 27 '07 #37
"karthikbalaguru" <ka***************@gmail.comschrieb im Newsbeitrag
On Sep 27, 3:30 pm, "ie...@free.fr" <ie...@free.frwrote:
>I also try a << 1
and it converted it into a + a

What is the optimisation level you have ?
Does it treat a<<1 and a*2 as a+a for all the optimisation levels ?
What is the architecture you use ?
I've checked with gcc on a pentium running Linux. It generates identical
code for a*2 and a<<1 in all optimization levels and identical code for a+a
with -O1 and higher (and only slightly different code with -O0).

Bye, Jojo
Sep 27 '07 #38
ie***@free.fr wrote:
I also try a << 1
and it converted it into a + a
Which presumably means that the designer of the compiler knew that it
was cheaper (fewer cycles) on the specific target architecture to add
"a" to itself than to use some other mechanism to achieve a 1-place left
shift.

If you don't want to trust the compiler writers to do a decent job of
optimisation, I suggest you move to writing assembler...
Sep 27 '07 #39
If you don't want to trust the compiler writers to do a decent job of
optimisation, I suggest you move to writing assembler...
No, no, I trust them. It's their work, not mine.
In beginning my question was theoretical.
The real meaning was, is << a left shift or something who shift the
numbers from the less important bit to the most important.
And people said it's the second, not the first.

Sep 27 '07 #40
On Sep 27, 6:07 pm, "ie...@free.fr" <ie...@free.frwrote:
If you don't want to trust the compiler writers to do a decent job of
optimisation, I suggest you move to writing assembler...

No, no, I trust them. It's their work, not mine.
In beginning my question was theoretical.
The real meaning was, is << a left shift or something who shift the
numbers from the less important bit to the most important.
And people said it's the second, not the first.
Onceagain,
You have not replied to the below questions -
1) What is the optimisation level you have ?
2) Does it treat a<<1 and a*2 as a+a for all the optimisation
levels ?
3) What is the architecture you use ?

Karthik Balaguru

Sep 27 '07 #41
I just need a precision about an operator. I saw many code with the
operator << and didn't know if it was portable.

Today I don't care if "<< 1" is faster than "* 2" or "+".

Sep 27 '07 #42
On Sep 27, 10:36 pm, "ie...@free.fr" <ie...@free.frwrote:
I just need a precision about an operator. I saw many code with the
operator << and didn't know if it was portable.

Today I don't care if "<< 1" is faster than "* 2" or "+".
You have not yest answered these questions which will clarify your
doubts .

1) What is the optimisation level you have ?
2) Does it treat a<<1 and a*2 as a+a for all the optimisation
levels ?
3) What is the architecture you use ?
4) Also tell about the compiler and programming language you use ?

Karthik Balaguru

Sep 27 '07 #43
"karthikbalaguru" <ka***************@gmail.comschrieb im Newsbeitrag
On Sep 27, 10:36 pm, "ie...@free.fr" <ie...@free.frwrote:
>I just need a precision about an operator. I saw many code with the
operator << and didn't know if it was portable.

Today I don't care if "<< 1" is faster than "* 2" or "+".

You have not yest answered these questions which will clarify your
doubts .

1) What is the optimisation level you have ?
As he said earlier (implicitly): no optimization
2) Does it treat a<<1 and a*2 as a+a for all the optimisation
levels ?
Yes (I've checked)
3) What is the architecture you use ?
From the assembly he posted: Intel ix86
4) Also tell about the compiler and programming language you use ?
gcc and C

Bye, Jojo
Sep 27 '07 #44
1) What is the optimisation level you have ?
>
As he said earlier (implicitly): no optimization
No, I used to use -O3, but when I post my example I used no
optimization.
2) Does it treat a<<1 and a*2 as a+a for all the optimisation
levels ?

Yes (I've checked)
Ha, interesting.
3) What is the architecture you use ?

From the assembly he posted: Intel ix86
686 to be exact (P4 I think).
>
4) Also tell about the compiler and programming language you use ?

gcc and C
We're in a C forum.

Sep 27 '07 #45
On Sep 27, 3:15 am, "ie...@free.fr" <ie...@free.frwrote:
Can you post the snapshot of the internal of a*2 and a+a that you
got ?

I can't, it was in past. But I'm sure. I asked a friend, and he
explain me that on some architecture (like the HP adding machine)
there wasn't a multiplication in the CPU, so the multiplication was a
software and it was better to use + than *. And it was not a lshift, I
swear it.
80% of the cost of software is maintenance.

So write code that is as clear and expressive as possible.

Do not try to out-think your compiler. Chances are very good that it
is better at optimization than you are.

If you *measure* a performance problem, then run a profiler against
the code to find out *where* the slow bits are. Typically, there will
be a couple places that need help. The way to fix these problem spots
is NOT by micro-optimizations like exchanging shifts for multiplies by
powers of two but by improving the algorithm. If (and only if) you
have measured to find out what is slow and you are unable to find or
produce a better algorithm, then it makes sense to do little tweaky
micro-optimizations or inline assembly. If you code that way from
scratch, then you are writing unmaintainable gobbledygook that won't
be fast anyway and will eventually cause great problems.

The first rule of optimization is: "Don't do it."
The second rule of optimization (for experts only) is: "Don't do it
yet."

Sep 27 '07 #46
80% of the cost of software is maintenance.
>
So write code that is as clear and expressive as possible.
I don't care. When I read my codes I understand them, even those I
wrote 10 years ago, I can't explain why but I never forget one of my
code, I know it's rare.

Read and modify others code is a concept which leads to bugs, you
can't say I'm wrong.
You want to change something. You clear his function and you rewrite
it, but you have to know what are is in and his out, so a great API
reference.

Forget the concept that others will read your code. If they do that
it's because your code is stinky, if it was good they don't need to
have a look. It's like try something and thinking since the beginning
that we are going to fail.

Sep 27 '07 #47
On Sep 27, 8:07 am, "ie...@free.fr" <ie...@free.frwrote:
In beginning my question was theoretical.
The real meaning was, is << a left shift or something who shift the
numbers from the less important bit to the most important.
And people said it's the second, not the first.

The C standard defines a<<b to be a shift operations, and further
defines that it will be equivalent to ((a*(2**b))mod Uxxx_MAX) for
unsigned a's and non-negative b's.

For signed first operands, if the first operand is non-negative, and
if the result of (a*(2**b)) is representable in the type, then that's
the result. Otherwise (in the case of overflow or negative first or
second operands) the result is undefined.

In both cases, shift counts larger than the first parameter's width in
bits also have undefined results.

Sep 27 '07 #48
ie***@free.fr wrote:
Hello guys, every time a rode a doc or a book about the language C I
saw that operators << and >exist. But each time they said that <<
translate the digit to the left (and >...) but no one said if a <<
1 mean every time a * 2, because there is the problem with the way
the integer are stored. So I never use thoses operators because I
fear strange behaviour on different architecture. Can I use them and
be sure that a << 1 means a * 2 on every computer ? Is is in the ansi
standard of language C ?

First, bitwise operators, are intended for bit level operations on
unsigned types. If a is negative, a << 1 is undefined behavior, i.e. not
portable at all.
There are some very confused C programmers, that beleave a << 1, somehow
is faster than a *= 2. Such micro-optimization has been *nonsense* for
quite some years, when considering an optimizing C compiler.
Modern optimizing C compilers these days, are so advanced, that even
expert asm programmers have hard times beating it, a C newbie have less
chance than a snowball in hell.
Elsethread, somebody said one could count cycles from asm listing and
just compare timings. This typically not true, instructions can be
executed out-of-band, there can be multiple pipelines operating in
parallel, there can be branch-prediction etc. etc.
Optimizing these days, is a cache game.

If optimizing, focus rather on good algorithms, and keep
locality/compactness of data. Leave the rest to the compiler.

--
Tor <torust [at] online [dot] no>

"Premature tuning is the root of all evil"
Sep 27 '07 #49
karthikbalaguru wrote:
"ie...@free.fr" <ie...@free.frwrote:
>>
.... snip ...
>>
Today I don't care if "<< 1" is faster than "* 2" or "+".

You have not yest answered these questions which will clarify your
doubts .

1) What is the optimisation level you have ?
2) Does it treat a<<1 and a*2 as a+a for all the optimisation
levels ?
3) What is the architecture you use ?
4) Also tell about the compiler and programming language you use ?
For heavens sake, give it up. Such answers have nothing to do with
the question in the first place.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Sep 27 '07 #50

### This discussion thread is closed

Replies have been disabled for this discussion.