# Ciclos por instrucción

En arquitectura de computadores, los ciclos por instrucción o CPI son una medida del rendimiento de un procesador: el número medio de ciclos de reloj por instrucción en un programa o fragmento. Es el inverso multiplicativo de las instrucciones por ciclo.

## Definición

Los ciclos por instrucción se definen como
    $\mathrm {CPI} ={\frac {\Sigma _{i}(\mathrm {IC} _{i})(\mathrm {CC} _{i})}{\mathrm {IC} }}$
donde $\mathrm {IC} _{i}$ es el número de instrucciones de un tipo determinado $i$, $\mathrm {CC} _{i}$ es el número de ciclos de reloj que tarda en ejecutarse ese tipo de instrucciones y $\mathrm {IC} =\Sigma _{i}(\mathrm {IC} _{i})$ es el número total de instrucciones. El sumatorio suma sobre todos los tipos de instrucción.

## Explicación

Supongamos un procesador segmentado con las siguientes cinco etapas:
* Ciclo de búsqueda de instruction (IF).
* Ciclo de decodificación de instrucción/acceso a registros (ID).
* Ciclo de ejecución/dirección efectiva (EX).
* Acceso a memoria (MEM).
* Ciclo de escritura (WB).
Cada etapa necesita un ciclo de reloj y cada instrucción pasa secuencialmente por todas las etapas. Sin segmentación, se inicia la ejecución de una nueva instrucción en la primera etapa solo después de que la instrucción anterior termine en la última fase, por tanto el número de ciclos de reloj que se tarda en ejecutar cada instrucción es cinco (CPI = 5 > 1). En este caso, se dice que el procesador es subescalar. Con segmentación, se inicia una nueva instrucción cada ciclo de reloj para explotar el paralelismo a nivel de instrucción. Por tanto, dado que teóricamente se pueden tener cinco instrucciones en cada una de las cinco etapas del procesador, una instrucción diferente completaría su última etapa cada ciclo de reloj y por tanto idealmente el número de ciclos que se tarda en ejecutar cada instrucción es de media 1 (CPI = 1). En este caso, se dice que el procesador es escalar.
En un procesador con una sola unidad funcional, el mejor CPI alcanzable es 1. Sin embargo, en un procesador con varias unidades funcionales, se pueden conseguir incluso mejores valores de CPI (CPI < 1). En este caso, se dice que el procesador es superescalar. Para conseguir mejores valores de CPI sin segmentación, el número de unidades funcionales debe ser mayor que el número de etapas. Por ejemplo, con seis unidades funcionales, en la primera fase se inicia la ejecución den seis nuevas instrucciones solo después de que las seis instrucciones previas finalizan en la última fase, por tanto de media el número de ciclos que se tarda en ejecutar cada instrucción es 5/6 (CPI = 5/6 < 1). Para conseguir mejores valores de CPI con segmentación, debe haber al menos dos unidades funcionales. Por ejemplo, con dos unidades funcionales, se inician dos nuevas instrucciones cada ciclo explotando el paralelismo a nivel de instrucción, por tanto idealmente dos instrucciones diferentes completarían su última fase cada ciclo de reloj y de media el número de ciclos que se tarda en ejecutar cada instrucción es 1/2 (CPI = 1/2 < 1).

## Ejemplos
### Ejemplo 1

El procesador MIPS tiene cinco tipos de instrucciones:
* Carga (5 ciclos)
* Almacenamiento (4 ciclos)
* Tipo R (4 ciclos)
* Salto condicional (3 ciclos)
* Salto incondicional (3 ciclos)
Si un programa tiene:
* 50% de instrucciones de carga
* 15% de instrucciones de tipo R
* 25% de instrucciones de almacenamiento
* 8% de instrucciones de salto condicional
* 2% de instrucciones de salto incondicional
Entonces, el CPI es:
    ${\text{CPI}}={\frac {5\times 50+4\times 15+4\times 25+3\times 8+3\times 2}{100}}=4,4$

### Ejemplo 2

Se usa un procesador de 400 MHz para ejecutar un benchmark con el siguiente número de instrucciones y su tiempo de ejecución en ciclos de reloj:
| Tipo de instrucción | Número de instrucciones | Número de ciclos |
| Aritmética entera | 45000 | 1 |
| Transferencia de datos | 32000 | 2 |
| Punto flotante | 15000 | 2 |
| Transferencia de control | 8000 | 2 |
Vamos a determinar el CPI efectivo, los MIPS (millones de instrucciones por segundo), y el tiempo de ejecución del programa.
    ${\text{CPI}}={\frac {45000\times 1+32000\times 2+15000\times 2+8000\times 2}{100000}}={\frac {155000}{100000}}=1,55$
Dado que $\mathrm {MIPS} \propto 1/\mathrm {CPI}$ y $\mathrm {MIPS} \propto {\text{frecuencia de reloj}}$
    ${\text{Rendimiento del procesador}}={\text{MIPS}}={\frac {\text{frecuencia de reloj}}{\text{CPI}}}\times {\frac {1}{\text{1 000 000}}}={\frac {400000000}{1,55\times 1000000}}={\frac {400}{1,55}}=258\,{\text{MIPS}}$
Por tanto, el tiempo de ejecución será:
    ${\text{T}}={\text{CPI}}\times {\text{Número de instrucciones}}\times {\text{tiempo de reloj}}={\frac {{\text{CPI}}\times {\text{Número de instrucciones}}}{\text{frecuencia}}}={\frac {1,55\times 100000}{400\times 1000000}}={\frac {1,55}{4000}}=0,0003875\,{\text{s}}=0,3875\,{\text{ms}}$