traduccion rotacion operadores operaciones manejo ejemplos derecha corrimiento bitwise c bit-manipulation bitwise-operators cpu-architecture digital-logic

rotacion - operadores de bits javascript



¿Por qué las operaciones bitwise fueron un poco más rápidas que las operaciones de suma/resta en microprocesadores más antiguos? (6)

Me encontré con este extracto hoy:

En la mayoría de los microprocesadores antiguos, las operaciones a nivel de bits son ligeramente más rápidas que las operaciones de suma y resta y, por lo general, significativamente más rápidas que las operaciones de multiplicación y división. En arquitecturas modernas, este no es el caso: las operaciones a nivel de bits son generalmente la misma velocidad que la suma (aunque aún más rápido que la multiplicación).

Tengo curiosidad acerca de por qué las operaciones bitwise fueron ligeramente más rápidas que las operaciones de suma / resta en microprocesadores antiguos.

Todo lo que puedo pensar que causaría la latencia es que los circuitos para implementar la suma / resta dependen de varios niveles de compuertas lógicas (sumadores paralelos y otras cosas), mientras que las operaciones a nivel de bits tienen implementaciones de circuitos mucho más simples. ¿Es esta la razón?

Sé que tanto las operaciones aritméticas como las bit a bit se ejecutan dentro de un ciclo de reloj en los procesadores modernos, pero hablando puramente sobre el tiempo de propagación del circuito, ¿sigue existiendo teóricamente la latencia en los procesadores modernos?

Finalmente, tuve una pregunta conceptual en C sobre la ejecución de la operación de cambio a nivel de bits:

unsigned x = 1; x <<= 5; unsigned y = 0; y += 32;

Tanto x como y deberían mantener el valor 32 , pero, ¿se necesitaron 5 turnos a la izquierda para obtener x en ese valor (como los desplazamientos a nivel de bits implementados a través de tuberías)? Para aclarar, estoy preguntando puramente sobre el comportamiento del circuito, no sobre el número de ciclos de reloj.


Algunas implementaciones adicionales tienen que hacer un ciclo adicional para el bit de acarreo. Por ejemplo: un entero de 16 bits requiere varias instrucciones en un procesador de 8 bits. Esto también es válido para el cambio. Pero el desplazamiento siempre puede desplazar los bits de altura a los bits más bajos del siguiente byte. La adición debe agregar el bit inferior en una ronda adicional.


En cualquier operación binaria a nivel de bit, cada bit de salida depende solo de los dos bits correspondientes en las entradas. En una operación de adición, cada bit de salida depende de los bits correspondientes en las entradas y de todos los bits a la derecha (hacia valores más bajos).

Por ejemplo, el bit más a la izquierda de 01111111 + 00000001 es 1, pero el bit más a la izquierda de 01111110 + 00000001 es 0.

En su forma más simple, un sumador agrega los dos bits bajos y produce un bit de salida y un acarreo. Luego se agregan los siguientes dos bits más bajos y se agrega el acarreo, produciendo otro bit de salida y otro acarreo. Esto se repite. Así que el bit de salida más alto está al final de una cadena de agregados. Si realiza la operación bit a bit, como hicieron los procesadores anteriores, entonces lleva tiempo llegar al final.

Hay formas de acelerar esto, introduciendo varios bits de entrada en arreglos lógicos más complicados. Pero eso, por supuesto, requiere más área en el chip y más poder.

Los procesadores de hoy tienen muchas unidades diferentes para realizar diversos tipos de trabajo: cargas, almacenes, sumas, multiplicaciones, operaciones de punto flotante y más. Dadas las capacidades actuales, el trabajo de hacer un agregado es pequeño en comparación con otras tareas, por lo que se ajusta a un solo ciclo de procesador.

Quizás en teoría podría hacer un procesador que hiciera una operación a nivel de bits más rápido que un complemento. (Y hay, al menos en papel, procesadores exóticos que funcionan de forma asíncrona, con diferentes unidades que trabajan a su propio ritmo). Sin embargo, con los diseños en uso, necesita un ciclo fijo regular para coordinar muchas cosas en el procesador: carga instrucciones, enviándolos a unidades de ejecución, enviando resultados de unidades de ejecución a registros, y mucho, mucho más. Algunas unidades de ejecución requieren múltiples ciclos para completar sus trabajos (por ejemplo, algunas unidades de punto flotante toman aproximadamente cuatro ciclos para hacer un agregado de punto flotante). Así que puedes tener una mezcla. Sin embargo, con las escalas actuales, hacer que el tiempo del ciclo sea más pequeño para que se ajuste a una operación a nivel de bits pero no a un agregado probablemente no sea económico.


Esto brillaba desde una introducción a la clase de montaje. Pero el cambio es la instrucción más rápida que puede ejecutar un procesador. Agregar y restar requiere algunas instrucciones para ejecutar. Me imagino que los procesadores modernos están mejor optimizados.

Presumiblemente, alguien puede responder a esto de manera más precisa y completa.


Lo complicado de agregar (por lo general, se resta de forma gratuita) es que existe ese problema de transporte molesto.

Entonces, terminas con la ingenua solución siendo N veces Full-Adders donde N es la cantidad de bits de ancho que tiene tu ALU.

Estos comportamientos molestos significan que tienes un gran retraso de propagación. Y, debido a que un solo traslado puede hacer que el resultado completo sea inexacto, terminará teniendo que esperar una cantidad de tiempo bastante significativa para que todos los valores de acarreo y, a su vez, todos los demás sumadores completos de la cadena se liquiden.

Hay muchas formas de evitar este cuello de botella en particular, pero ninguna es tan simple o económica de implementar como una cadena de sumadores completos. (el más rápido es una tabla de búsqueda implementada en silicio)

Si desea más detalles, probablemente deba preguntar esto en http://electronics.stackexchange.com en su lugar


Operador poco inteligente se ejecuta en menos tiempo, porque

  • el procesador toma una instrucción para realizar operaciones de bits y (digamos) toma un ciclo de ejecución, por otro lado, otras instrucciones aritméticas (especialmente, multiplica y divide) toma más ciclos de ejecución
  • La mayor parte del tiempo la operación de bit bit se realiza con un registro y otras instrucciones aritméticas necesarias para manejar más de un registro.

Es por eso que los bits de desplazamiento son más rápidos que otras operaciones aritméticas


Para responder a tu última pregunta, depende. Algunas arquitecturas solo tienen cambios en 1 (como z80), algunas arquitecturas exponen cambios en constantes y / o variables más grandes, pero las implementan internamente como un grupo de "cambios por 1" (como las implementaciones antiguas de x86), hay Algunas arquitecturas pueden cambiar más de 1 en un solo ciclo, pero solo si la cantidad de desplazamiento es una constante, hay algunas arquitecturas (como las implementaciones modernas de x86) que usan una palanca de cambios de barril y pueden cambiar de una variable en un solo ciclo. , y todavía hay más posibilidades.

La profundidad del circuito de un desplazador de barril es logarítmica en el cambio máximo que puede hacer, que no es necesariamente el ancho de un registro; a veces es uno menos que el ancho y es posible que sea incluso menor.