Pregunta

Que se compila en un código más rápido:¿"ans = n * 3" o "ans = n+(n*2)"?

Suponiendo que n es int o long, y se ejecuta en una caja Intel Win32 moderna.

¿Sería esto diferente si hubiera alguna desreferenciación involucrada, es decir, cuál de estos sería más rápido?

long    a;
long    *pn;
long     ans;

...
*pn = some_number;
ans = *pn * 3;

O

ans = *pn+(*pn*2);

¿O es algo de lo que no hay que preocuparse, ya que es probable que la optimización de los compiladores tenga en cuenta esto en cualquier caso?

¿Fue útil?

Solución

En mi opinión, dicha microoptimización no es necesaria a menos que trabaje con algún compilador exótico.Yo pondría la legibilidad en primer lugar.

Otros consejos

No importa.Los procesadores modernos pueden ejecutar una instrucción MUL entera en un ciclo de reloj o menos, a diferencia de los procesadores más antiguos que necesitaban realizar una serie de cambios y sumas internamente para realizar el MUL, utilizando así múltiples ciclos.apostaría que

MUL EAX,3

se ejecuta más rápido que

MOV EBX,EAX
SHL EAX,1
ADD EAX,EBX

El último procesador en el que este tipo de optimización podría haber sido útil fue probablemente el 486.(Sí, esto está sesgado hacia los procesadores Intel, pero probablemente también sea representativo de otras arquitecturas).

En cualquier caso, cualquier compilador razonable debería poder generar el código más pequeño/rápido.Así que siempre opte por la legibilidad primero.

Como es fácil medirlo usted mismo, ¿por qué no hacerlo?(Usando gcc y time de cygwin)

/* test1.c */
int main()
{
    int result = 0;
    int times = 1000000000;
    while (--times)
        result = result * 3;
    return result;
}

machine:~$ gcc -O2 test1.c -o test1
machine:~$ time ./test1.exe

real    0m0.673s
user    0m0.608s
sys     0m0.000s

Haz la prueba un par de veces y repite en el otro caso.

Si quieres echar un vistazo al código ensamblador, gcc -S -O2 test1.c

Esto dependería del compilador, su configuración y el código circundante.

No deberías intentar adivinar si las cosas son "más rápidas" sin tomar medidas.

En general No deberías preocuparte por este tipo de optimización a nanoescala hoy en día; casi siempre es completamente irrelevante, y si realmente estuvieras trabajando en un dominio donde importara, ya estarías usando un generador de perfiles y mirando la salida en lenguaje ensamblador del compilador. .

No es difícil descubrir qué está haciendo el compilador con su código (aquí estoy usando DevStudio 2005).Escriba un programa simple con el siguiente código:

int i = 45, j, k;
j = i * 3;
k = i + (i * 2);

Coloque un punto de interrupción en la línea media y ejecute el código usando el depurador.Cuando se active el punto de interrupción, haga clic derecho en el archivo fuente y seleccione "Ir al desmontaje".Ahora tendrás una ventana con el código que está ejecutando la CPU.Notarás en este caso que las dos últimas líneas producen exactamente las mismas instrucciones, es decir, "lea eax,[ebx+ebx*2]" (sin desplazamiento de bits ni suma en este caso particular).En una CPU IA32 moderna, probablemente sea más eficiente realizar un MUL directo en lugar de un cambio de bits debido a la naturaleza de canalización de la CPU, que genera una penalización cuando se utiliza un valor modificado demasiado pronto.

Esto demuestra de qué está hablando aku, es decir, los compiladores son lo suficientemente inteligentes como para elegir las mejores instrucciones para su código.

Depende del compilador que estés utilizando, pero muy probablemente se traduzcan al mismo código.

Puedes comprobarlo tú mismo creando un pequeño programa de prueba y comprobando su desmontaje.

La mayoría de los compiladores son lo suficientemente inteligentes como para descomponer una multiplicación de números enteros en una serie de desplazamientos y sumas de bits.No sé acerca de los compiladores de Windows, pero al menos con gcc puedes hacer que escupe el ensamblador, y si miras eso, probablemente puedas ver un ensamblador idéntico para ambas formas de escribirlo.

No le importa.Creo que hay cosas más importantes que optimizar.¿Cuánto tiempo ha invertido pensando y escribiendo esa pregunta en lugar de codificarla y probarla usted mismo?

:-)

Mientras estés usando un compilador de optimización decente, simplemente escribir código que sea fácil de entender para el compilador.Esto facilita que el compilador realice optimizaciones inteligentes.

Si hace esta pregunta indica que un compilador de optimización sabe más sobre optimización que usted.Así que confía en el compilador.Usar n * 3.

Mira esto esta respuesta también.

Los compiladores son buenos optimizando códigos como el suyo.Cualquier compilador moderno produciría el mismo código para ambos casos y además reemplazaría * 2 por un desplazamiento hacia la izquierda.

Confíe en su compilador para optimizar pequeños fragmentos de código como ese.La legibilidad es mucho más importante a nivel de código.La verdadera optimización debería llegar a un nivel superior.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top