Bit shift

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Bit shift

Will Godfrey
Does anyone know if GCC will replace power of 2 multiplications/divisions of
unsigned integers with bit shifts?

--
Will J Godfrey
http://www.musically.me.uk
Say you have a poem and I have a tune.
Exchange them and we can both have a poem, a tune, and a song.
_______________________________________________
Linux-audio-dev mailing list
[hidden email]
https://lists.linuxaudio.org/listinfo/linux-audio-dev
Reply | Threaded
Open this post in threaded view
|

Re: Bit shift

Karl Hammar
Will Godfrey:
> Does anyone know if GCC will replace power of 2 multiplications/divisions of
> unsigned integers with bit shifts?

Test on your system:

$ cat a.c
#include <stdint.h>

int main(int argc, char *argv[]) {
  uint16_t b = argc * 2;

  return b;
}
$ gcc -S a.c
$ cat a.s
...
main:
.LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        movl    %edi, -20(%rbp)
        movq    %rsi, -32(%rbp)
        movl    -20(%rbp), %eax
        addl    %eax, %eax
        movw    %ax, -2(%rbp)
        movzwl  -2(%rbp), %eax
        popq    %rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
...
$

It seems it just adds the value with itself here.

Regards,
/Karl Hammar
_______________________________________________
Linux-audio-dev mailing list
[hidden email]
https://lists.linuxaudio.org/listinfo/linux-audio-dev
Reply | Threaded
Open this post in threaded view
|

Re: Bit shift

Will Godfrey
On Wed, 13 Mar 2019 00:09:17 +0100 (CET)
[hidden email] wrote:

>Will Godfrey:
>> Does anyone know if GCC will replace power of 2 multiplications/divisions of
>> unsigned integers with bit shifts?  
>
>Test on your system:
>
>$ cat a.c
>#include <stdint.h>
>
>int main(int argc, char *argv[]) {
>  uint16_t b = argc * 2;
>
>  return b;
>}
>$ gcc -S a.c
>$ cat a.s
>...
>main:
>.LFB0:
>        .cfi_startproc
>        pushq   %rbp
>        .cfi_def_cfa_offset 16
>        .cfi_offset 6, -16
>        movq    %rsp, %rbp
>        .cfi_def_cfa_register 6
>        movl    %edi, -20(%rbp)
>        movq    %rsi, -32(%rbp)
>        movl    -20(%rbp), %eax
>        addl    %eax, %eax
>        movw    %ax, -2(%rbp)
>        movzwl  -2(%rbp), %eax
>        popq    %rbp
>        .cfi_def_cfa 7, 8
>        ret
>        .cfi_endproc
>...
>$
>
>It seems it just adds the value with itself here.
>
>Regards,
>/Karl Hammar

Thanks, that seems to hold true for a mixture of AMD and Intel machines.

--
It wasn't me! (Well actually, it probably was)

... the hard part is not dodging what life throws at you,
but trying to catch the good bits.
_______________________________________________
Linux-audio-dev mailing list
[hidden email]
https://lists.linuxaudio.org/listinfo/linux-audio-dev
Reply | Threaded
Open this post in threaded view
|

Re: Bit shift

Karl Hammar
Will Godfrey:
> On Wed, 13 Mar 2019 00:09:17 +0100 (CET)
> [hidden email] wrote:
>
> >Will Godfrey:
> >> Does anyone know if GCC will replace power of 2 multiplications/divisions of
> >> unsigned integers with bit shifts?  
...
> >$ cat a.c
> >#include <stdint.h>
> >
> >int main(int argc, char *argv[]) {
> >  uint16_t b = argc * 2;
> >
> >  return b;
> >}
> >$ gcc -S a.c
,,,
> >It seems it just adds the value with itself here.
...
> Thanks, that seems to hold true for a mixture of AMD and Intel machines.

BTW, testing with 4, 8 and 16 instead of 2, it does actually do bit
shifts:

$ diff a.02.s a.04.s
16c16
<       addl    %eax, %eax
---
>       sall    $2, %eax
$ diff a.02.s a.08.s
16c16
<       addl    %eax, %eax
---
>       sall    $3, %eax
$ diff a.02.s a.16.s
16c16
<       addl    %eax, %eax
---
>       sall    $4, %eax

Regards,
/Karl Hammar
_______________________________________________
Linux-audio-dev mailing list
[hidden email]
https://lists.linuxaudio.org/listinfo/linux-audio-dev
Reply | Threaded
Open this post in threaded view
|

Re: Bit shift

Jonathan E. Brickman
That is likely to change depending on GCC optimization setting, no?

J.E.B.

On Sat, Mar 16, 2019, 5:12 PM <[hidden email]> wrote:
Will Godfrey:
> On Wed, 13 Mar 2019 00:09:17 +0100 (CET)
> [hidden email] wrote:
>
> >Will Godfrey:
> >> Does anyone know if GCC will replace power of 2 multiplications/divisions of
> >> unsigned integers with bit shifts? 
...
> >$ cat a.c
> >#include <stdint.h>
> >
> >int main(int argc, char *argv[]) {
> >  uint16_t b = argc * 2;
> >
> >  return b;
> >}
> >$ gcc -S a.c
,,,
> >It seems it just adds the value with itself here.
...
> Thanks, that seems to hold true for a mixture of AMD and Intel machines.

BTW, testing with 4, 8 and 16 instead of 2, it does actually do bit
shifts:

$ diff a.02.s a.04.s
16c16
<       addl    %eax, %eax
---
>       sall    $2, %eax
$ diff a.02.s a.08.s
16c16
<       addl    %eax, %eax
---
>       sall    $3, %eax
$ diff a.02.s a.16.s
16c16
<       addl    %eax, %eax
---
>       sall    $4, %eax

Regards,
/Karl Hammar
_______________________________________________
Linux-audio-dev mailing list
[hidden email]
https://lists.linuxaudio.org/listinfo/linux-audio-dev

_______________________________________________
Linux-audio-dev mailing list
[hidden email]
https://lists.linuxaudio.org/listinfo/linux-audio-dev
Reply | Threaded
Open this post in threaded view
|

Re: Bit shift

Karl Hammar
J.E.B:
> That is likely to change depending on GCC optimization setting, no?

Then, why don't you just test it to find out, you have the means to
that after all.

Regards,
/Karl Hammar
_______________________________________________
Linux-audio-dev mailing list
[hidden email]
https://lists.linuxaudio.org/listinfo/linux-audio-dev
Reply | Threaded
Open this post in threaded view
|

Re: Bit shift

gordonjcp
In reply to this post by Jonathan E. Brickman
On Sun, Mar 17, 2019 at 11:56:40AM -0500, Jonathan Brickman wrote:
> That is likely to change depending on GCC optimization setting, no?
>

This is why you can't trust very high level languages like C, and should
be wary of high-level languages like assembler.

--
Gordonjcp
_______________________________________________
Linux-audio-dev mailing list
[hidden email]
https://lists.linuxaudio.org/listinfo/linux-audio-dev
Reply | Threaded
Open this post in threaded view
|

Re: Bit shift

Robin Gareus
In reply to this post by Jonathan E. Brickman
On 3/17/19 5:56 PM, Jonathan Brickman wrote:
> That is likely to change depending on GCC optimization setting, no?

Not usually. It depends on the target architecture more than anything.

Even with -O0, gcc translates integer addition and multiplications into
a combination of bitwise and arithmetic operations if that is
appropriate for the target CPU.


On 3/12/19 11:43 PM, Will Godfrey wrote:
> Does anyone know if GCC will replace power of 2
> multiplications/divisions of unsigned integers with bit shifts?
Not only power of two, and it depends. In some cases the compiler
doesn't replace it because the resulting code is not faster. Many modern
CPU already implement integer multiplication using bitwise operations in
microcode.

I don't know if this your question is academic, but if you plan to
manually optimize code, I highly recommend against that.

Write semantically! If you mean a multiplication, use (a * 2), if you
mean bit-shift use (a << 1). Do not use bitwise-operations when you
really do integer-arithmetics.

Your future self and code-contributers will thank you for it; as will
compilers targeting future CPU architectures.
</rant>

2c,
robin
_______________________________________________
Linux-audio-dev mailing list
[hidden email]
https://lists.linuxaudio.org/listinfo/linux-audio-dev
Reply | Threaded
Open this post in threaded view
|

Re: Bit shift

Will Godfrey
On Sun, 17 Mar 2019 20:12:04 +0100
Robin Gareus <[hidden email]> wrote:

>On 3/17/19 5:56 PM, Jonathan Brickman wrote:
>> That is likely to change depending on GCC optimization setting, no?  
>
>Not usually. It depends on the target architecture more than anything.
>
>Even with -O0, gcc translates integer addition and multiplications into
>a combination of bitwise and arithmetic operations if that is
>appropriate for the target CPU.
>
>
>On 3/12/19 11:43 PM, Will Godfrey wrote:
>> Does anyone know if GCC will replace power of 2
>> multiplications/divisions of unsigned integers with bit shifts?  
>Not only power of two, and it depends. In some cases the compiler
>doesn't replace it because the resulting code is not faster. Many modern
>CPU already implement integer multiplication using bitwise operations in
>microcode.
>
>I don't know if this your question is academic, but if you plan to
>manually optimize code, I highly recommend against that.
>
>Write semantically! If you mean a multiplication, use (a * 2), if you
>mean bit-shift use (a << 1). Do not use bitwise-operations when you
>really do integer-arithmetics.
>
>Your future self and code-contributers will thank you for it; as will
>compilers targeting future CPU architectures.
></rant>
>
>2c,
>robin


Thanks Robin. Very clear. It's the direction I was beginning to think in. It's
sometimes difficult to imagine how far compilers have advanced over the years.

--
Will J Godfrey
http://www.musically.me.uk
Say you have a poem and I have a tune.
Exchange them and we can both have a poem, a tune, and a song.
_______________________________________________
Linux-audio-dev mailing list
[hidden email]
https://lists.linuxaudio.org/listinfo/linux-audio-dev