Solo quería saber qué operación es más rápida en C / C ++, así como cuál es la complejidad computacional para un tipo de conversión.

Tipificación de x a un entero sin signo así:

(unsigned int) x

O

Realizando una comparación entre x y una constante:

x<0

Editar: complejidad computacional en cuanto a qué proceso requiere la menor cantidad de operaciones de bits en un aspecto de bajo nivel del hardware para llevar a cabo con éxito la instrucción.

edición n. ° 2: para dar un poco de contexto, lo que estoy tratando de hacer específicamente es ver si reducir

if( x < 0)

En

if((((unsigned int)x)>>(((sizeof(int))<<3)-1)))

Sería más eficiente o no si se hiciera más de 100.000.000 de veces, con grandes cantidades para x, arriba / abajo (+/-) 50.000.000

0
ILove Anime 28 ene. 2016 a las 08:39

3 respuestas

La mejor respuesta

(unsigned int) x es, para la notación de complemento de 2 casi universal, una operación en tiempo de compilación: le está diciendo al compilador que trate el contenido de x como un valor unsigned, lo cual no requieren cualquier instrucción de código de máquina en tiempo de ejecución en sí mismo, pero pueden cambiar las instrucciones de código de máquina que emite para admitir el uso realizado del valor unsigned, o incluso causar optimizaciones de eliminación de código muerto, por ejemplo, lo siguiente podría ser eliminado completamente después del yeso:

if ((unsigned int)my_unsigned_int >= 0)

La cita estándar de C ++ relevante (mi negrita):

Si el tipo de destino no tiene signo, el valor resultante es el menor entero sin signo congruente con el entero de origen (módulo 2 n donde n es el número de bits utilizados para representar el tipo sin signo). [ Nota : En dos complemento , esta conversión es conceptual y no hay ningún cambio en el patrón de bits (si no hay truncamiento) . —Nota final]

Podría haber un cambio bit a bit real que requiera una operación en algún hardware extraño usando el complemento de 1 o representaciones de signo / magnitud. (Gracias Yuushi por resaltar esto en los comentarios).

Eso contrasta con x < 0, que - para un x firmado sobre el cual el compilador no tiene un conocimiento especial, requiere una instrucción de CPU / código de máquina para evaluar (si se usa el resultado) y el tiempo de ejecución correspondiente. Esa instrucción de comparación tiende a tomar 1 "ciclo" incluso en CPU más antiguas, pero tenga en cuenta que las canalizaciones de CPU modernas pueden ejecutar muchas de estas instrucciones en paralelo durante un solo ciclo.

if( x < 0) vs if((((unsigned int)x)>>(((sizeof(int))<<3)-1))) - ¿más rápido?

El primero siempre será al menos tan rápido como el segundo. Una comparación con cero es una operación básica para la CPU, y el compilador de C ++ seguramente usará un código de operación eficiente (instrucción de código de máquina) para ello: está perdiendo el tiempo tratando de mejorar eso.

5
Tony Delroy 28 ene. 2016 a las 06:34

Para responder a su pregunta editada real, es poco probable que sea más rápido. En el mejor de los casos, si se conoce x en el momento de la compilación, el compilador podrá optimizar la rama completamente en ambos casos.

Si x es un valor de tiempo de ejecución, entonces el primero producirá una única instrucción de prueba. El segundo probablemente producirá un cambio a la derecha inmediatamente seguido de una instrucción de prueba.

0
Yuushi 28 ene. 2016 a las 06:37

El monstruo if((((unsigned int)x)>>(((sizeof(int))<<3)-1))) será más lento que el sencillo if(x < 0): ambas versiones necesitan comparar un valor con cero, pero tu monstruo agrega un cambio antes de que se pueda realizar la comparación.

0
cmaster - reinstate monica 28 ene. 2016 a las 06:36