#include <stdio.h>
#include <string.h>
#include <assert.h>
/*
* Implements http://stackoverflow.com/a/25541929/466611
*/
static inline unsigned int test1(int n)
{
return (1u << n) - 1;
}
/*
* Implements http://stackoverflow.com/a/25541942/466611
*/
static inline unsigned int test2(int n)
{
return 0xffffffff >> (32 - n);
}
int main(int argc, char **argv)
{
assert((argc == 2) || (argc == 3));
unsigned int repeat = 1 << 24;
if (argc > 2)
repeat = atol(argv[2]);
if (!strcmp("test1", argv[1]))
{
volatile unsigned int tmp;
unsigned int i;
for (i = 0; i < repeat; i++)
tmp = test1(i & 31);
}
else if (!strcmp("test2", argv[1]))
{
volatile unsigned int tmp;
unsigned int i;
for (i = 0; i < repeat; i++)
tmp = test2(i & 31);
}
else
assert(0);
return 0;
}
[pengyu@GLaDOS tmp]$ gcc a.c -O2
[pengyu@GLaDOS tmp]$ time ./a.out test1
real 0m0.031s
user 0m0.027s
sys 0m0.003s
[pengyu@GLaDOS tmp]$ time ./a.out test2
real 0m0.040s
user 0m0.037s
sys 0m0.000s
[pengyu@GLaDOS tmp]$ cat /proc/cpuinfo | grep "model name" | head -n 1
model name : Intel(R) Core(TM) i7-3740QM CPU @ 2.70GHz
[pengyu@GLaDOS tmp]$ uname -a
Linux GLaDOS 3.16.1-1-ARCH #1 SMP PREEMPT Thu Aug 14 07:40:19 CEST 2014 x86_64 GNU/Linux
[pengyu@GLaDOS tmp]$ gcc --version | head -n 1
gcc (GCC) 4.9.1
[pengyu@GLaDOS tmp]$ ld --version | head -n 1
GNU ld (GNU Binutils) 2.24
Generated using: gcc a.c -O2 -S -fverbose-asm
Core function code for test1
:
92 .L6:
93 movl %eax, %edx # tmp126, D.2768
94 sall %cl, %edx # i, D.2768
95 addl $1, %ecx #, i
96 subl $1, %edx #, D.2768
97 cmpl %ecx, %ebx # i, repeat
98 movl %edx, 24(%rsp) # D.2768, tmp
99 ja .L6 #,
Core function code for test2
:
124 .L8:
125 movl %edx, %eax # i, D.2767
126 movl %edi, %ecx # tmp127, D.2767
127 addl $1, %edx #, i
128 andl $31, %eax #, D.2767
129 subl %eax, %ecx # D.2767, D.2767
130 movl %esi, %eax # tmp128, D.2768
131 shrl %cl, %eax # D.2767, D.2768
132 cmpl %ebx, %edx # repeat, i
133 movl %eax, 28(%rsp) # D.2768, tmp
134 jne .L8 #,