2010-09-16 13 views
8

Me gustaría saber si realizar un cambio de sentido lógico a la derecha es más rápido cuando se cambia con una potencia de 2. Estoy usando C++.¿Es un cambio lógico a la derecha con una potencia de 2 más rápida?

Por ejemplo, es

myUnsigned >> 4 

más rápido que

myUnsigned >> 3 

Soy consciente de que la primera respuesta de todo el mundo estará de decirme que no hay que preocuparse por pequeñas cosas como esta, que es utilizando algoritmos y colecciones correctos para cortar órdenes de magnitud que importan. Estoy totalmente de acuerdo contigo, pero realmente estoy tratando de sacar todo lo que pueda de un chip integrado (un ATMega328) - ¡Acabo de obtener un cambio de rendimiento digno de un 'woohoo'! reemplazando una división con un cambio de bit, entonces te prometo que esto sí importa.

Gracias.

+8

¿Por qué no se mide usted mismo? –

+7

¿A quién le importa si 'x >> 4' es más rápido que' x >> 3'? Tienen una semántica diferente, por lo que no importa cuál es más rápido. De todos modos, nunca he encontrado una arquitectura en la que el operando correcto de un operador de desplazamiento de bits tenga algún impacto en el rendimiento. – fredoverflow

+4

@FredOverflow: en el ATMega, la instrucción de cambio de bit no toma un operando de "número de bits para cambiar". En cuanto a 'x >> 4' contra' x >> 3' - tal vez el OP tiene algunas libertades aquí (por ejemplo, haciendo aritmética de punto fijo y tiene una cierta cantidad de latitud en qué tan grande es el componente fraccional) –

Respuesta

17

Vamos en la ficha técnica:

http://atmel.com/dyn/resources/prod_documents/8271S.pdf

Por lo que yo puedo ver, el ASR (desplazamiento aritmético a la derecha) siempre se desplaza en un bit y no puede tomar el número de bits a desplazar; toma un ciclo para ejecutarse. Por lo tanto, el desplazamiento en n bits llevará n ciclos. Los poderes de dos se comportan igual que cualquier otro número.

+0

¡Gracias! Tuve que reemplazar un número de coma flotante con un número entero, pero tenía que multiplicarlo para mantener la precisión. Estoy tratando de encontrar un coeficiente ideal para que pase el menor tiempo posible crujiendo el int hasta el tamaño sin multiplicar. – Will

1

Si su procesador de targer tiene una instrucción de cambio de bit (lo cual es muy probable), depende de la implementación de hardware de esa instrucción si habrá alguna diferencia entre cambiar una potencia de 2 bits o cambiar algún otro número. Sin embargo, es poco probable que haga la diferencia.

4

Para obtener esta información, debe consultar la documentación de su procesador. Incluso para un conjunto de instrucciones dado, puede haber diferentes costos dependiendo del modelo. En un procesador realmente pequeño, el cambio por uno podría ser más rápido que por otros valores, por ejemplo (es el caso de las instrucciones de rotación en algunos procesadores IA32, pero eso es solo porque los compiladores rara vez producen esta instrucción).

Según http://atmel.com/dyn/resources/prod_documents/8271S.pdf todos los cambios lógicos se realizan en un ciclo para el ATMega328. Pero, por supuesto, como se señala en los comentarios, todos los cambios lógicos son de un bit. Entonces, el costo de un cambio por n es n ciclos en n instrucciones. mirada

+0

Cuidado: las instrucciones de cambio siempre se desplazan en un solo bit ... cambio, más tiempo lleva. –

+1

+1 para investigar la CPU específica. –

+0

@Martin B Gracias por señalar, debería haberlo notado, la información estaba disponible en el mismo PDF. –

0

Con todo respeto, ni siquiera debería comenzar a hablar sobre el rendimiento hasta que comience a medir. Compila tu programa con división. Correr. Medir el tiempo. Repita con el turno.

+1

Dado que ya ha medido una mejora en el rendimiento reemplazando div con shift, creo que es bastante evidente que ha estado cronometrando. – Crashworks

+0

AFAIK es un asunto ampliamente conocido sobre cálculos computacionales que los PO de desplazamiento son mucho más rápidos que los de multiplicación, la división es más lenta que la multiplicación (son más lentos incluso en el papel)). La suma/resta son casi tan rápidas como los cambios, solo que en teoría usan un poco más de transistores, pero no importa y la CPU los ejecuta en un solo ciclo de todos modos. multiplicación y división toman más ciclos – Mixaz

+0

multiplicación y división toman más ciclos, ya que usan suma/resta internamente en iteraciones posteriores. Recuerdo que las especificaciones de ARM (al menos para las versiones anteriores) establecían que la división (no recuerdo acerca de la multiplicación) puede tomar otro tiempo, debido a que – Mixaz

4

En el AVR instruction set, el desplazamiento aritmético hacia la derecha y hacia la izquierda se realiza de a un bit a la vez. Por lo tanto, para este microcontrolador en particular, cambiar >> n significa que el compilador realmente hace n muchas operaciones individuales asr, y supongo que >>3 es una más rápida que >>4.

Esto hace que el AVR sea bastante inusual, por cierto.

+0

no es inusual. La mayoría (si no todos) los microcontroladores de 8 bits no tienen una palanca de cambios y deben cambiar un bit a la vez –

2

Depende de cómo esté construido el procesador. Si el procesador tiene una rotación de barril, puede cambiar cualquier cantidad de bits en una operación, pero eso requiere espacio en el chip y un presupuesto de energía. El hardware más económico simplemente podría rotar uno por uno, con opciones relacionadas con el bit de ajuste. El siguiente sería uno que podría rotar uno hacia la izquierda o hacia la derecha. Me puedo imaginar una estructura que tendría una 1-shifter, 2-shifter, 4-shifter, etc.en cuyo caso 4 podría ser más rápido que 3.

1

Desarmar primero y cronometrar el código. No se desanime por las personas que le dicen, usted está perdiendo el tiempo. El conocimiento que obtienes te pondrá en posición de ser la persona perfecta para apagar los grandes incendios de la compañía. La cantidad de personas con conocimiento real detrás de la cortina está cayendo a un ritmo alarmante en esta industria.

Suena como que otros explicaron la verdadera respuesta aquí, que el desmontaje habría mostrado, instrucciones de cambio de bit único. Entonces 4 turnos tomarán el 133% del tiempo que tomaron 3 turnos, o 3 turnos es el 75% del tiempo de 4 turnos, dependiendo de cómo comparaste los números. Y sus mediciones deberían reflejar esa diferencia, si no lo hicieran, continuaría con este experimento hasta que comprenda completamente los tiempos de ejecución.

0

de hecho ATMega tiene una instrucción de intercambio de nibble. Así turno x << 4 puede ser más rápido que x << 3

x << 3 se implementa en un 3 izquierda mueven

x <<= 1; 
x <<= 1; 
x <<= 1; 

mientras que x << 4 sólo es necesario un intercambio y un poco clara

swap(x); // swap the top and bottom nibble AB <-> BA 
x &= 0xf0; 

o

x &= 0x0f; 
swap(x); 

o si puedes ma Asegúrese de que los 4 bits superiores sean cero, entonces basta con un intercambio de nibble

swap(x); 
+0

Hm, no sabía que x << 3 en AVR se implementa como 3 turnos. ¿Estás seguro de que AVR tiene un OP especial para un cambio de bit único? En el intercambio de ARM y << 3 tomaría el mismo tiempo (1 ciclo) – Mixaz

+1

@Mixaz no hay microcontrolador de 8 bits Sé que tiene palanca de cambios, por lo que solo puede cambiar 1 bit en cada ciclo. Simplemente busque el conjunto de instrucciones AVR, PIC o 8051 y consulte –

+0

Incluso algunos microcontroladores de 16 bits aún tienen que cambiar 1 bit cada vez. El conjunto de instrucciones de ARV se publicó en las otras respuestas, léelo primero –

Cuestiones relacionadas