Solo para ilustrar, basado en la respuesta de FredOverflow (que es buen trabajo, felicitaciones y +1), una trampa común con respecto a las sucursales en x86. Aquí está la asamblea de FredOverflow como salida por gcc:
movl 8(%ebp), %edx #1/.5
movl %edx, %eax #1/.5
andl $-16777216, %eax#1/.5
cmpl $1, %eax #1/.5
sbbl %eax, %eax #8/6
addl $4, %eax #1/.5
xorl %ecx, %ecx #1/.5
testl $-65536, %edx #1/.5
sete %cl #5
subl %ecx, %eax #1/.5
andl $-256, %edx #1/.5
sete %dl #5
movzbl %dl, %edx #1/.5
subl %edx, %eax #1/.5
# sum total: 29/21.5 cycles
(la latencia, en ciclos, se ha de leer como Prescott/Northwood)
conjunto optimizado a mano (también kudos) de Pascal Cuoq:
cmpl $255, %edi #1/.5
setg %al #5
addb $3, %al #1/.5
cmpl $65535, %edi #1/.5
setle %dl #5
subb %dl, %al #1/.5
cmpl $16777215, %edi #1/.5
setle %dl #5
subb %dl, %al #1/.5
movzbl %al, %eax #1/.5
# sum total: 22/18.5 cycles
Editar: la solución de FredOverflow usando __builtin_clz()
:
movl 8(%ebp), %eax #1/.5
popl %ebp #1.5
orb $-1, %al #1/.5
bsrl %eax, %eax #16/8
sarl $3, %eax #1/4
addl $1, %eax #1/.5
ret
# sum total: 20/13.5 cycles
una nd el conjunto de gcc para su código:
movl $1, %eax #1/.5
movl %esp, %ebp #1/.5
movl 8(%ebp), %edx #1/.5
cmpl $255, %edx #1/.5
jbe .L3 #up to 9 cycles
cmpl $65535, %edx #1/.5
movb $2, %al #1/.5
jbe .L3 #up to 9 cycles
cmpl $16777216, %edx #1/.5
sbbl %eax, %eax #8/6
addl $4, %eax #1/.5
.L3:
ret
# sum total: 16/10 cycles - 34/28 cycles
en la que va a buscar la línea de caché de instrucciones que vienen como el efecto secundario de las instrucciones jcc
tal vez le cueste nada para una función tan corto.
Las sucursales pueden ser una elección razonable, dependiendo de la distribución de entrada.
Editar: se agregó la solución de FredOverflow que está usando __builtin_clz()
.
Dudo que esto se pueda hacer mucho más rápido. – MAK
¡Guau! Más de 10 millones de veces ... ¿Quiere decir que si aprieta tres ciclos de esta función, ahorrará tanto como 0.03s? –
No sé cuánto tiempo esto realmente seguro. Voy por un libro sobre C/C++ donde dice que si las condiciones son típicamente mucho más lentas que las bitoperaciones. – raisyn