Cómo funcionan los pipelines de un CPU
Transcript of Cómo funcionan los pipelines de un CPU
Cómo funcionan los pipelines de un CPU
14 Junio 2006
Compartido0Veces
En computación, se le llama pipeline a una serie de elementos de procesamiento de
datos ordenados de tal modo que la salida de cada uno es la entrada del siguiente,
como quien dice una cadena de montaje pero en vez de orientada a la
manufactura, orientada al procesamiento de datos e instrucciones. En esta guía
explicaremos cómo funcionan.
Esta guía es la adaptación de un contenido original situado en Ars Technica
(Understanding Pipelining Performance), con cuyo permiso contamos para esta
publicación.
Introducción
En computación, se le llama pipeline a una serie de elementos de procesamiento de
datos ordenados de tal modo que la salida de cada uno es la entrada del siguiente, como
quien dice una cadena de montaje pero en vez de orientada a la manufactura, orientada
al procesamiento de datos e instrucciones.
Entender cómo funciona un pipeline es un paso importante para entender qué diablos
ocurre dentro de un procesador, y es por eso que en esta guía, que hemos separado en
dos capítulos, intentaremos dejarte en claro el sentido y mecánica de estas cadenas de
montaje que existen al interior de un CPU.
El material que vas a leer fué licenciado a partir de un documento facilitado por
Arstechnica, el cual fué traducido y adaptado por CHW para el mejor entendimiento de
nuestro público.
El Pentium 4 y sus pipelines
El Pentium 4 original era un diseño radical por un número de razones, pero quizás su
característica más llamativa (y polémica a la vez) era su "pipelining" o "segmentación"
extraordinariamente profunda. Con más de 20 etapas, los "pipes" del Pentium 4 eran
casi dos veces más profundos que los "pipes" de sus competidores. Recientemente el
Prescott, sucesor de los Pentium 4 en 90nm, llevó el "pipelining" a un nivel superior,
agregando otras 10 etapas sobre los "pipes" del Pentium 4.
La estrategia de Intel de profundizar el pipeline del Pentium 4, una práctica que Intel
llama "hyperpipelining", ha dado sus frutos en términos del funcionamiento, pero no sin
sus desventajas. En artículos anteriores sobre el Pentium 4 y Prescott, me he referido a
las desventajas asociadas a los "pipes" profundos, e incluso he intentado explicar estas
desventajas dentro del contexto de artículos técnicos más grandes sobre Netburst y otros
asuntos. En la actual serie de artículos, dedicaré bastante tiempo a explicar el
"pipelining", su efecto sobre funcionamiento del microprocesador, y sus desventajas
potenciales. Después de una introducción básica sobre el concepto de los "pipes",
explicaré qué se requiere para hacer "pipes" eficientes y qué desventajas presentan
diseños con pipelines profundos como el Prescott. Para el final del artículo, debes tener
un claro entendimiento de cómo la profundidad de los "pipes" se relaciona con el
funcionamiento del microprocesador en diversos tipos de código.
Ciclo de vida de una instrucción
La acción básica de cualquier microprocesador, en tanto se mueve a través de la
corriente de instrucciones, se puede descomponer en una serie de cuatro pasos simples,
que cada instrucción en la corriente de código debe atravesar para ser ejecutada:
1. Fetch: "traer" la instrucción que se va a ejecutar, de la dirección almacenada
en el contador de programa.
2. Store: "almacenar" la instrucción en el registro de instrucciones y
"descifrarla", incrementando la dirección en el contador de programa.
3. Execute: "Ejecutar" la instrucción almacenada en el registro de instrucciones.
Si la instrucción no es una instrucción de rama sino una instrucción aritmética,
este proceso la envía a la ALU apropiada (ALU: Arithmetic Logic Unit – en
español: Unidad Aritmético-Lógica), donde el microprocesador: a. "Lee" el
contenido de los registros de entrada. b. "Agrega" el contenido de los registros
de entrada.
4. Write: "Escribir" los resultados de esa instrucción de la ALU nuevamente
dentro del registro de destinación
En un procesador moderno, los cuatro pasos arriba descritos son repetidos una y otra
vez hasta que el programa termine de ejecutarse. Éstas son, en hecho, las cuatro etapas
en un "pipe" clásico del RISC. (Definiré el término "pipe" pronto; por ahora, piensen en
un "pipe" como serie de etapas que cada instrucción en la corriente de código debe
atravesar cuando se está ejecutando dicha corriente de código.)
Aquí están las cuatro etapas en su forma abreviada, que es la más común y la que verás
más a menudo:
1. Fetch (Traer)
2. Decode (Descifrar)
3. Execute (Ejecutar)
4. Write (Escribir)
Cada uno de los conceptos anteriores puede ser usado para representar una fase en el
"ciclo de vida" de una instrucción. Una instrucción comienza en la fase de "traer", se
mueve a la fase de "descifrar", después a la fase "ejecutar", y finalmente a la fase
"escribir". Cada fase toma un tiempo fijo, pero de ningún modo igual al que otra fase
toma en cumplir su cometido.
En la mayoría de los ejemplos de procesadores con los que trabajaremos en este
artículo, las cuatro fases tomarán la misma cantidad de tiempo; éste no es generalmente
el caso en procesadores del mundo real. De cualquier manera, si el procesador simple
del ejemplo toma exactamente 1 nanosegundo para terminar cada etapa, entonces el
procesador puede acabar una instrucción cada 4 nanosegundos.
Fundamentos del "Pipelining": una analogia.
Esta sección utiliza una analogía del sistema productivo de una fábrica para explicar el
termino "pipelining". Otras personas utilizan analogías más simples, como lavar la ropa,
por ejemplo, para explicar esta técnica, pero hay ciertas razones por las que elegí una
analogía más elaborada y más larga para ilustrar cuál es la raíz de este concepto
relativamente simple.
Primero, las fábricas basadas en líneas de ensamblaje hacen fácil la visualización, y la
imagen mental del proceso se puede elaborar de muchas maneras interesantes, con el fin
de exponer una variedad de puntos relacionados. En segundo lugar, y quizás más
importante, la gran complejidad de programación que deben enfrentar los diseñadores
de la fábrica para ordenar y administrar los recursos tiene análogos directos en la
arquitectura de computadores. En muchos casos, los problemas y las soluciones son
exactamente iguales, llevadas simplemente a un dominio diferente.
Digamos que mis amigos y yo hemos decidido entrar el negocio de fabricación
automotriz, y que nuestro primer producto debe ser un vehículo deportivo para uso
general (SUV). Después de cierta investigación, determinamos que hay cinco etapas en
el proceso de ensamblaje del SUV:
Etapa 1: Construir el chasis.
Etapa 2: Poner el m
otor en el chasis.
Etapa 3: Poner puertas, el capó y las cubiertas en el chasis.
Etapa 4: Poner las ruedas.
Etapa 5: Pintar el SUV.
Cada una de las etapas de arriba requiere el uso de trabajadores altamente entrenados
con habilidades específicas, y sucede que los trabajadores que son buenos para armar
los chasis no saben sobre los motores, carrocería, las ruedas, o pintar, y lo mismo pasa
con los constructores de motores, los pintores, y los demás equipos de trabajo. Así que
cuando hacemos nuestra primera tentativa de poner una fábrica de SUV, empleamos y
entrenamos a cinco equipos de especialistas, uno para cada etapa del proceso de
construcción de los SUV. Hay un equipo para construir el chasis, uno para poner el
motor, otro para las ruedas, y un equipo para la pintura. Finalmente, siendo los equipos
tan especializados y eficientes, cada etapa del proceso de construcción del SUV le toma
exactamente una hora a cada equipo.
Ahora, puesto que mis amigos y yo somos simplemente geeks y no ingenieros
industriales, teníamos mucho que aprender sobre la fabricación y del uso eficiente de los
recursos de la fábrica. Basamos el funcionamiento de nuestra primera fábrica en el
siguiente plan: colocamos a los cinco equipos en una línea en el piso de la fábrica, y al
comienzo de la línea tenemos al equipo 1 trabajando. Después de que la etapa 1 se
completa, el equipo de la etapa 1 pasa la SUV parcialmente terminada al equipo de la
etapa 2 y después se van a descansar (para jugar un poco de taca-taca), mientras que el
equipo de la etapa 2 construye el motor y lo coloca en el chasis. Una vez que el equipo
termina la etapa 2, el SUV pasa a la etapa 3 y el equipo de la etapa 3 asume el control
mientras que el equipo de la etapa 2 se une al equipo de la etapa 1 para jugar taca-taca.
El SUV pasa por la línea a través de las cinco etapas de esta manera, con solamente un
equipo trabajando en cada etapa en cualquier hora dada mientras que el resto de los
equipos descansa. Una vez que el SUV terminado acabe la etapa 5, el equipo en la etapa
1 comienza el otro SUV. A este ritmo, toma exactamente cinco horas para acabar un
solo SUV, y nuestra fábrica termina un SUV cada cinco horas.
Nos pegamos un salto al futuro de un año. Nuestro SUV, el ChwDelorian LE, se vende
como... bueno, se vende como un SUV, lo que significa que le va muy bien. De hecho,
se vende tan bien (a pesar de llamarse así) que hemos captado la atención de las FF.AA.
y nos ofrecen un contrato millonario para proveer ChwDelorians al Ejército, de manera
sostenida y creciente. Las FF.AA. son exigentes, quieren ordenar múltiples
ChwDelorians a la vez; puede llegar una orden por 10 ChwDelorians tan fácilmente
como una de 500. Mientras más de estas órdenes podamos cumplir por año fiscal, más
dinero podremos lavar... ejem!, ganar en ese período, con el resultado de que nuestras
hojas de balance ya no parezcan calendario -¡puros números azules desde ahora! Esto,
obviamente, significa que tendremos que encontrar una manera de incrementar la
cantidad de vehículos que nuestra fábrica puede producir por hora (esto es, nuestra tasa
de producción de ChwDelorians). Construir más por hora significa que podemos
cumplir los pedidos del Ejército más rápidamente, y eso significa "we can make more
money, baby!
La forma más intuitiva para incrementar nuestra tasa de producción sería reducir el
tiempo de producción de cada vehículo. Si, ya sea mediante presiones laborales o
económicas, lográsemos que nuestros equipos trabajen al doble de velocidad, nuestra
fábrica podría producir el doble de vehículos en un mismo tiempo de trabajo. Pero
nuestros equipos ya están trabajando tan duro como pueden, así que a menos que haya
una irrupción tecnológica que incremente su productividad, ser negreros no es una
solución viable.
Sin poder acelerar nuestros equipos, siempre existe la alternativa de usar la fuerza bruta
y simplemente inyectar dinero al problema con la construcción de una segunda línea de
ensamblaje. Si fuésemos a contratar y entrenar cinco nuevos equipos para formar esta
línea, con la misma capacidad de producir un vehículo cada cinco horas, podríamos
completar el asombroso total de... ¡Dos! ChwDelorians cada cinco horas – el doble de
nuestra tasa de producción actual. Pero esto no es muy eficiente en términos del uso de
los recursos de la producción, pues no solamente tenemos el doble de equipos
trabajando a la vez: también tenemos el doble de equipos usando el taca-taca a la vez y
eso sí que es un problema tremendo. Debe haber una manera "más mejol" de hacer las
cosas.
Enfrentados a la falta de opciones, contratamos a una consultora para encontrar una
manera inteligente de incrementar la producción total de la fábrica sin doblar el número
de equipos ni sobreexplotar los actuales. Un año después, y varias lucas mediante, los
consultores aparecen con una solución: "¿Por qué deberían nuestros empleados pasarse
4/5 del día jugando taca-taca, tomando cafecito y leyendo Chilehardware, si podrían
estar haciendo trabajo útil durante ese tiempo? Con una apropiada programación de los
cinco equipos existentes, nuestra fábrica podría completar un ChwDelorian por hora, y
así mejorar dramáticamente la eficiencia y el volumen de producción de nuestra línea de
ensamblaje. El sistema revisado, se vería más o menos así: el equipo 1 construye un
chasis. Una vez que el chasis está completo, lo envían al equipo 2 para que ensamblen el
motor, mientras empiezan la construcción de un nuevo chasis. Cuando los equipos 1 y 2
están listos, el trabajo del equipo 2 avanza hacia el equipo 3, el del equipo 1 al equipo 2,
y el equipo 1 comienza a construir un nuevo chasis."
Así, en tanto la línea de ensamblaje comienza a llenarse con vehículos en diferentes
etapas de producción, los equipos se ponen a trabajar simultáneamente hasta que todos
están trabajando en un vehículo diferente, en diferentes etapas de producción. (Por
supuesto, así es como debería ser, para la mayoría de nosotros, una línea de ensamblaje
eficiente en la era post-Ford). Si podemos mantener la línea llena, manteniendo a todos
los equipos trabajando a la vez, entonces podemos producir un ChwDelorian cada hora:
un incremento de 5x sobre la tasa de producción anterior. Eso, mis estimados
contertulios, vendría siendo el "pipelining".
Mientras que el tiempo total consumido en cada etapa de producción no ha cambiado de
las 5 horas originales, la tasa a la cual la fábrica como un todo completa los autitos, y
por ende la tasa a la cual la fábrica puede cumplir los pedidos del Ejército, ha
aumentado drásticamente. El pipelining hace su truco con la optimización total de los
recursos existentes. No necesitamos acelerar cada etapa individual del proceso
productivo, ni tampoco incrementar descabelladamente la cantidad de recursos que
inyectamos al problema; todo lo que necesitamos es obtener más trabajo de los recursos
que ya existen.
Volviendo a los microprocesadores, debiera ser fácil el ver cómo este concepto se aplica
a las cuatro fases del ciclo de vida de una instrucción. Tal como los propietarios de la
fábrica en nuestra analogía querían incrementar el número de ChwDelorians que podían
producir en un tiempo det
erminado, los diseñadores de microprocesadores siempre están buscando formas de
incrementar el número de instrucciones que un CPU puede completar en un período de
tiempo dado. Cuando recordamos que un programa es una secuencia ordenada de
instrucciones, se hace claro que incrementar el número de instrucciones ejecutadas por
unidad de tiempo es una forma de disminuir el tiempo total de ejecución de un
programa. En términos de nuestra analogía, un programa es como una orden de
ChwDelorians del Ejército; tal como el incremento de nuestra tasa de producción nos
permite completar pedidos más rápidamente, incrementar la tasa de proceso de
instrucciones de nuestro procesador (esto es, el número de instrucciones completadas
por unidad de tiempo) nos permite correr programas más rápido.
Un ejemplo sin pipelining.
Tiempo atrás, los procesadores sin pipelining trabajaban sobre una instrucción a la vez,
moviendo cada instrucción a través de las cuatro fases de su ciclo de vida en el tiempo
de un ciclo de reloj. Así, los procesadores sin pipeline se llaman también procesadores
de ciclo simple, porque todas las instrucciones toman exactamente un ciclo de reloj para
ejecutarse completamente (o, para pasar a través de las cuatro fases de sus ciclos de
vida).
Como el procesador completa instrucciones al ritmo de una por ciclo de reloj, queremos
que el reloj del CPU corra lo más rápidamente posible, para que la tasa de ejecución de
instrucciones del procesador (esto es, el número de instrucciones completadas por
nanosegundo) sea tan alta como sea posible. Así necesitamos calcular la mínima
cantidad de tiempo que toma completar una instrucción, y hacer el ciclo de reloj
equivalente a esa longitud de tiempo. Simplemente pasa que en nuestro caso hipotético
de CPU, las cuatro fases del ciclo de vida de la instrucción toman un total de cuatro
nanosegundos para completarse, por lo tanto deberíamos setear la duración del ciclo de
reloj del CPU a cuatro nanosegundos, así el CPU puede completar todo el ciclo de vida
de la instrucción, desde fetch hasta write-back, en un solo ciclo. (Un ciclo de reloj de
CPU es simplemente denominado ciclo.)
Figure PIPELINING.4: Procesador de un solo ciclo.
En el diagrama superior, la instrucción azul deja el área de almacenamiento de código
entra al procesador, y avanza a través de las fases de su ciclo de vida en el curso del
ciclo de cuatro nanosegundos, hasta que el final del cuarto nanosegundo completa la
última fase y su ciclo de vida se acaba Sad El fin del cuarto nanosegundo es también el
fin del primer ciclo de reloj, por lo tanto ahora que el primer ciclo terminó y la
instrucción azul ha completado su ejecución, la instrucción roja puede entrar al
procesador al comienzo de un nuevo ciclo de reloj y cruzar el mismo proceso. Esta
secuencia de pasos en cuatro nanosegundos se repite hasta que, después de un total de
16ns (o cuatro ciclos de reloj) el procesador ha completado las cuatro instrucciones a un
ritmo de 0.25 instrucciones /ns (=4 instrucciones/16ns).
Procesadores de ciclo simple como el de la figura PIPELINING 4 son simples de
diseñar, pero desperdician un montón de recursos de hardware. Todo el espacio blanco
en el diagrama representa hardware de proceso que permanece inactivo mientras espera
que termine de ejecutarse la instrucción actual. Haciendo "pipelining" al procesador,
podemos poner a trabajar más de ese hardware en cada nanosegundo, incrementando de
esa manera la eficiencia del procesador y su performance en la ejecución de programas.
Antes de seguir, debo clarificar unos cuantos aspectos del diagrama anterior que alguien
puede encontrar confusos. Al final del diagrama hay una región nombrada "Completed
Instructions" o "instrucciones completadas". Ahora, las instrucciones completadas se
van al limbo una vez que se terminan de ejecutar; después de decirle al procesador
como modificar la corriente de datos, son simplemente borradas del procesador. (Nota
que las instrucciones que han sido borradas del procesador aún permanecen en el área
de almacenamiento de código y están disponibles para su uso repetido.) Entonces la
cajita "Completed Instructions" o "instrucciones completadas" al final de la figura
PIPELINING.4 no representa una parte real del computador, razón por la cual he puesto
una línea punteada a su alrededor. Esta área es sólo un lugar para que mantengamos
registro de cuántas instrucciones ha completado el procesador en cierto intervalo de
tiempo, o la tasa de ejecución de instrucciones del procesador (o tasa de ejecución, para
abreviar), de manera que cuando comparemos diferentes tipos de procesadores
tendremos un lugar al cual podremos mirar rápidamente y obtener una impresión
instantánea de cuál procesador se desempeña mejor. Mientras más instrucciones
complete un procesador en una cantidad de tiempo dada, mejor es su desempeño en los
programas, lo cuales son secuencias ordenadas de instrucciones. Así que piensa en la
cajita de "instrucciones completadas" como una especie de marcador para registrar la
tasa de ejecución de cada procesador, y chequea la cajita en cada uno de los siguientes
diagramas para ver cuánto le toma al procesador poblar esta cajita con instrucciones
ejecutadas.
Siguiendo con el punto anterior, te puede intrigar por qué la instrucción azul completada
en el cuarto nanosegundo no aparece en la cajita "instrucciones completadas" antes del
quinto nanosegundo. La razón es simple, y emana de la naturaleza del diagrama: en
tanto una instrucción gasta un nanosegundo completo en cada etapa de ejecución, la
instrucción azul entra en la fase de escritura al principio del cuarto nanosegundo y
termina dicha etapa al final del cuarto nanosegundo. Esto significa que recién en el
quinto nanosegundo tenemos completa la instrucción azul. Así, al comienzo del quinto
nanosegundo (que coincide con el fin del cuarto) el procesador ha completado una
instrucción.
Un ejemplo con pipelining.
Hacer "pipelining" a un procesador significa descomponer su proceso de ejecución de
instrucciones – lo que hemos estado llamando el "ciclo de vida" de la instrucción- en
una serie de etapas discretas de segmentación, que pueden ser completadas en secuencia
por hardware especializado. Recuerda la manera en que dividimos el proceso de
ensamblaje del vehículo en cinco etapas discretas, con un equipo dedicado asignado al
cumplimiento de cada etapa, y tendrás el panorama claro.
En tanto el ciclo de vida de una instrucción consiste en cuatro fases completamente
distintas, podemos empezar por descomponer el proceso de ejecución de instrucciones
de nuestro procesador de ciclo simple en una secuencia de cuatro etapas discretas de
segmentación – un pipeline de cuatro etapas-, donde cada etapa corresponde a una fase
en el ciclo de vida estándar de la instrucción:
Etapa 1: Traer la instrucción desde el almacén de código.
Etapa 2: Decodificar la instrucción.
Etapa 3: Ejecutar la instrucción.
Etap
a 4: Escribir los resultados de la instrucción en el archivo de registro.
Observa que nos referimos al número de etapas del pipeline como profundidad del
pipeline. Entonces, nuestro pipeline de 4 etapas tiene una profundidad de pipeline igual
a 4.
Por conveniencia, digamos que cada una de las cuatro etapas del pipeline anterior toma
exactamente un nanosegundo para terminar su trabajo con una instrucción, tal como
cada equipo en nuestra línea de ensamblaje demoraba una hora en terminar su porción
de trabajo en el vehículo. Entonces nuestro proceso de 4 nanosegundos, en nuestro
procesador de ciclo simple, se divide ahora en 4 etapas de pipeline discretas y
secuenciales de un nanosegundo de longitud cada una. Ahora observemos otro diagrama
para ver cómo un CPU con pipeline ejecutaría las cuatro instrucciones descritas en la
figura PIPELINING.4.
Al comienzo del primer nanosegundo, la instrucción azul entra en la etapa de fetch
(traer). Comienza el segundo nanosegundo y la instrucción azul se mueve a la etapa de
decodificación mientras la siguiente instrucción, la roja, se abre camino desde el
almacén de código al procesador (esto es, entra a la etapa de fetch). Al comienzo del
tercer nanosegundo, la instrucción azul avanza a la etapa de ejecución, la instrucción
roja a la etapa de decodificación, y la instrucción verde entra a la etapa de fetch. En el
cuarto, la instrucción azul avanza a la etapa de escritura, la roja a la de ejecución, la
verde a la decodificación, y la violeta a la de fetch. Cuando se ha completado el cuarto
nanosegundo y comienza el quinto, la instrucción azul ha pasado a través del pipeline y
ha terminado su ejecución. Así podemos decir que al final de cuatro nanosegundos (= a
cuatro ciclos de reloj) el procesador con pipeline ha completado una instrucción.
Al comienzo del quinto nanosegundo, el pipeline está completo y el procesador puede
empezar a completar instrucciones al ritmo de una instrucción por nanosegundo. Esta
tasa de ejecución de 1 instrucción/ns es un incremento de 4x sobre la tasa del
procesador de ciclo simple, que era 0.25 instrucciones/ns (o 4 instrucciones cada 16
nanosegundos)
Encogiendo el reloj.
Puedes ver en el diagrama anterior que el rol del reloj del CPU cambia levemente en un
procesador con pipeline, versus el procesador de ciclo simple en la figura
PIPELINING.4. Como ahora todas las etapas del pipeline deben trabajar
simultáneamente y estar listas al comienzo de cada nanosegundo para para pasar los
resultados de su trabajo a la siguiente etapa, el reloj es necesario para coordinar la
actividad del pipeline completo. La forma en que eso se hace es simple: reducir el
tiempo del ciclo de reloj para ajustarse al tiempo que le toma a cada etapa el completar
su trabajo, de manera que al comienzo de cada ciclo de reloj las distintas etapas
entregan la instrucción en la que estaban trabajando a la siguiente etapa. Como cada
pipeline en nuestro procesasdor de ejemplo se toma un nanosegundo en completar su
trabajo, podemos setear el ciclo de reloj en un nanosegundo.
Este nuevo método para ajustar el clock del procesador significa que una instrucción
nueva no necesariamente se completará al final de cada ciclo, como en el caso del
procesador de ciclo simple. En vez de eso, solo al final de aquellos ciclos donde se
trabaja en la etapa de escritura, se puede hablar de instrucciones completadas. Los ciclos
que tengan la etapa de escritura en blanco no añadirán nuevas instrucciones a la cajita
de "instrucciones completadas", y todo ciclo con una etapa de escritura activa añadirá
una nueva instrucción a la caja. Por supuesto, esto significa que al comenzar a trabajar
en un programa habrá algunos ciclos de reloj – tres para ser exactos- en los cuales no se
registrarán instrucciones completadas. Pero una vez que comience el cuarto ciclo, la
primera instrucción entrará en la etapa de escritura y el pipeline podrá comenzar a
ejecutar nuevas instrucciones en cada ciclo, las cuales tendrán un ritmo de ejecución de
1 instrucción/ns, pues cada ciclo tiene un nanosegundo de longitud.
Encogiendo el tiempo de ejecución de programa.
Observa que el pipelining no cambia el tiempo total de ejecución para cada instrucción
individual. Cada instrucción se toma aún 4ns para abrirse camino en el procesador; esos
4ns pueden ser divididos en 4 ciclos e 1ns cada uno o en 1 solo gran ciclo, pero son los
mismos 4ns. Así, el pipelining no acelera la velocidad de ejecución de instrucciones,
pero acelera el tiempo de ejecución de programas (esto es, el número de nanosegundos
que toma un programa completo en ejecutarse) incrementando el número de
instrucciones terminadas por unidad de tiempo. Tal como el pipelining en nuestra
cadena de ensamblaje de ChwDelorians nos permite completar los pedidos del Ejército
en un menor intervalo de tiempo (aún cuando seguimos demorando las mismas 5 horas
en ensamblar un vehículo), el pipelining le permite a un procesador ejecutar programas
en un tiempo menor aún cuando cada instrucción individual sigue consumiendo el
mismo tiempo viajando a través del CPU. El pipelining hace un uso más eficiente de los
recursos disponibles del CPU poniendo todas sus unidades a trabajar simultáneamente,
permitiéndole de esta forma realizar más trabajo total por cada nanosegundo.