Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% encontró este documento útil (0 votos)
60 vistas34 páginas

Aac Vector

Descargar como pdf o txt
Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1/ 34

Captulo 1

Procesadores vectoriales
En el camino hacia los multiprocesadores y multicomputadores nos encontramos con
los procesadores vectoriales que son una forma tambien de procesamiento paralelo.
Normalmente el calculo cientfico y matematico precisa de la realizacion de un
n
umero elevado de operaciones en muy poco tiempo. La mayora de los problemas
fsicos y matematicos se pueden expresar facilmente mediante la utilizacion de matrices
y vectores. Aparte de que esto supone una posible claridad en el lenguaje, va a permitir
explotar al maximo un tipo de arquitectura especfica para este tipo de tipos de datos,
y es la de los procesadores vectoriales.
El paralelismo viene de que al operar con matrices, normalmente, los elementos
de las matrices son independientes entre s, es decir, no existen dependencias de datos
dentro de las propias matrices, en general. Esto permite que todas las operaciones entre
elementos de unas matrices con otras puedan realizarse en paralelo, o al menos en el
mismo cauce de instrucciones sin que haya un conflicto entre los datos.
Otra ventaja del calculo matricial es que va a permitir replicar las unidades de calculo
sin necesidad de replicar las unidades de control. Se tendra en este caso una especie de
multiprocesador sin necesidad de tener que replicar tanto la unidad de control como la
de calculo, eso s, el n
umero de tareas que un sistema de este tipo podra abordar son
limitadas.
Los procesadores vectoriales se caracterizan porque van a ofrecer una serie de operaciones de alto nivel que operan sobre vectores, es decir, matrices lineales de n
umeros.
Una operacion tpica de un procesador vectorial sera la suma de dos vectores de coma
flotante de 64 elementos para obtener el vector de 64 elementos resultante. La instruccion en este caso es equivalente a un lazo software que a cada iteracion opera sobre
uno de los 64 elementos. Un procesador vectorial realiza este lazo por hardware aprovechando un cauce mas profundo, la localidad de los datos, y una eventual repeticion
de las unidades de calculo.
Las instrucciones vectoriales tienen unas propiedades importantes que se resumen a
continuacion aunque previamente ya se han dado unas pinceladas:
El calculo de cada resultado es independiente de los resultados anteriores en el
mismo vector, lo que permite un cauce muy profundo sin generar riesgos por las
dependencias de datos. La ausencia de estos riesgos viene decidida por el compilador
o el programador cuando se decidio que la instruccion poda ser utilizada.
Una sola instruccion vectorial especifica una gran cantidad de trabajo, ya que equiIngeniera Informatica

Universidad de Valencia

Procesadores vectoriales

vale a ejecutar un bucle completo. Por lo tanto, el requisito de anchura de banda de


las instrucciones se reduce considerablemente. En los procesadores no vectoriales,
donde se precisan muchas mas instrucciones, la b
usqueda y decodificacion de las
instrucciones puede representar un cuello de botella, que fue detectado por Flynn
en 1966 y por eso se le llama cuello de botella de Flynn.
Las instrucciones vectoriales que acceden a memoria tienen un patron de acceso
conocido. Si los elementos de la matriz son todos adyacentes, entonces extraer el
vector de un conjunto de bancos de memoria entrelazada funciona muy bien. La
alta latencia de iniciar un acceso a memoria principal, en comparacion con acceder
a una cache, se amortiza porque se inicia un acceso para el vector completo en lugar
de para un u
nico elemento. Por ello, el coste de la latencia a memoria principal se
paga una sola vez para el vector completo, en lugar de una vez por cada elemento
del vector.
Como se sustituye un bucle completo por una instruccion vectorial cuyo comportamiento esta predeterminado, los riesgos de control en el cauce, que normalmente
podran surgir del salto del bucle, son inexistentes.
Por estas razones, las operaciones vectoriales pueden hacerse mas rapidas que una
secuencia de operaciones escalares sobre el mismo n
umero de elementos de datos, y
los dise
n adores estan motivados para incluir unidades vectoriales si el conjunto de las
aplicaciones las puede usar frecuentemente.
El presente captulo ha sido elaborado a partir de [HP96], [HP93] y [Hwa93]. Como
lecturas adicionales se puede ampliar la informacion con [Sto93] y [HB87].

1.1
1.1.1

Procesador vectorial b
asico
Arquitectura vectorial b
asica

Un procesador vectorial esta compuesto tpicamente por una unidad escalar y una unidad vectorial. La parte vectorial permite que los vectores sean tratados como n
umeros
en coma flotante, como enteros o como datos logicos. La unidad escalar es un procesador
segmentado normal y corriente.
Hay dos tipos de arquitecturas vectoriales:
M
aquina vectorial con registros: en una maquina de este tipo, todas las operaciones vectoriales, excepto las de carga y almacenamiento, operan con vectores
almacenados en registros. Estas maquinas son el equivalente vectorial de una arquitectura escalar de carga/almacenamiento. La mayora de maquinas vectoriales
modernas utilizan este tipo de arquitectura. Ejemplos: Cray Research (CRAY-1,
CRAY-2, X-MP, Y-MP y C-90), los supercomputadores japoneses (NEC SX/2 y
SX/3, las Fujitsu VP200 y VP400 y la Hitachi S820)
M
aquina vectorial memoria-memoria: en estas maquinas, todas las operaciones
vectoriales son de memoria a memoria. Como la complejidad interna, as como el
coste, son menores, es la primera arquitectura vectorial que se empleo. Ejemplo:
el CDC.
El resto del captulo trata sobre las maquinas vectoriales con registros, ya que las
de memoria han cado en desuso por su menor rendimiento.
Ingeniera Informatica

Universidad de Valencia

1.1 Procesador vectorial basico

La figura 1.1 muestra la arquitectura tpica de una maquina vectorial con registros.
Los registros se utilizan para almacenar los operandos. Los cauces vectoriales funcionales cogen los operandos, y dejan los resultados, en los registros vectoriales. Cada
registro vectorial esta equipado con un contador de componente que lleva el seguimiento
del componente de los registros en ciclos sucesivos del cauce.
Procesador escalar
Cauces
funcionales
escalares
Procesador vectorial

Instrucciones escalares
Instrucciones vectoriales

Unidad de control
escalar

Unidad de control
vectorial
Control

Instrucciones
Datos
escalares

Memoria principal
(Programa y datos)

Almacenamiento
masivo

Computador
anfitrin
E/S

Cauce func. vectorial


Datos
vectoriales

Registros
Vectoriales
Cauce func. vectorial

Usuario

Figura 1.1: La arquitectura de un supercomputador vectorial.


La longitud de cada registro es habitualmente fija, como por ejemplo 64 componentes
de 64 bits cada uno como en un Cray. Otras maquinas, como algunas de Fujitsu, utilizan
registros vectoriales reconfigurables para encajar dinamicamente la longitud del registro
con la longitud de los operandos.
Por lo general, el n
umero de registros vectoriales y el de unidades funcionales es
fijo en un procesador vectorial. Por lo tanto, ambos recursos deben reservarse con
antelacion para evitar conflictos entre diferentes operaciones vectoriales.
Los supercomputadores vectoriales empezaron con modelos uniprocesadores como
el Cray 1 en 1976. Los supercomputadores vectoriales recientes ofrecen ambos modelos,
el monoprocesador y el multiprocesador. La mayora de supercomputadores de altas
prestaciones modernos ofrecen multiprocesadores con hardware vectorial como una caracterstica mas de los equipos.
Resulta interesante definirse una arquitectura vectorial sobre la que explicar las
nociones de arquitecturas vectoriales. Esta arquitectura tendra como parte entera la
propia del DLX, y su parte vectorial sera la extension vectorial logica de DLX. Los
componentes basicos de esta arquitectura, parecida a la de Cray 1, se muestra en la
figura 1.2.
Los componentes principales del conjunto de instrucciones de la maquina DLXV
son:
Registros vectoriales. Cada registro vectorial es un banco de longitud fija que contiene un solo vector. DLXV tiene ocho registros vectoriales, y cada registro vectorial
contiene 64 dobles palabras. Cada registro vectorial debe tener como mnimo dos
puertos de lectura y uno de escritura en DLXV. Esto permite un alto grado de
solapamiento entre las operaciones vectoriales que usan diferentes registros vectoriales.
Ingeniera Informatica

Universidad de Valencia

Procesadores vectoriales
Memoria principal

Carga/almacenamiento
vectorial
suma/resta FP
multiplicacin FP
divisin FP

Registros
vectoriales

Entero
Lgico

Registros
escalares

Figura 1.2: Estructura basica de una arquitectura vectorial con registros, DLXV.
Unidades funcionales vectoriales. Cada unidad se encuentra completamente segmentada y puede comenzar una nueva operacion a cada ciclo de reloj. Se necesita
una unidad de control para detectar conflictos en las unidades funcionales (riesgos
estructurales) y conflictos en los accesos a registros (riesgos por dependencias de
datos).
Unidad de carga/almacenamiento de vectores. Es una unidad que carga o almacena un vector en o desde la memoria. Las cargas y almacenamientos en DLXV
estan completamente segmentadas, para que las palabras puedan ser transferidas
entre los registros vectoriales y memoria, con un ancho de banda de una palabra
por ciclo de reloj tras una latencia inicial.
Conjunto de registros escalares. Estos tambien pueden proporcionar datos como
entradas a las unidades funcionales vectoriales, as como calcular direcciones para
pasar a la unidad de carga/almacenamiento de vectores. Estos seran los 32
registros normales de proposito general y los 32 registros de punto flotante del
DLX.
La figura 1.3 muestra las caractersticas de algunos procesadores vectoriales, incluyendo el tama
n o y el n
umero de registros, el n
umero y tipo de unidades funcionales, y
el n
umero de unidades de carga/almacenamiento.

1.1.2

Instrucciones vectoriales b
asicas

Principalmente las instrucciones vectoriales se pueden dividir en seis tipos diferentes.


El criterio de division viene dado por el tipo de operandos y resultados de las diferentes
instrucciones vectoriales:
1. Vector-vector: Las instrucciones vector-vector son aquellas cuyos operandos son
vectores y el resultado tambien es un vector. Suponiendo que Vi , Vj y Vk son
registros vectoriales, este tipo de instrucciones implementan el siguiente tipo de
funciones:
f1 : Vi Vj
Ingeniera Informatica

Universidad de Valencia

1.1 Procesador vectorial basico

Processor

Year
announced

Clock
rate
(MHz)

Registers

Elements per
register (64-bit
elements)

CRAY-1

1976

80

64

6: add, multiply, reciprocal,


integer add, logical, shift

CRAY X-MP
CRAY Y-MP

1983
1988

120
166

64

8: FP add, FP multiply, FP reciprocal, integer add, 2 logical,


shift, population count/parity

2 loads
1 store

CRAY-2

1985

166

64

5: FP add, FP multiply, FP reciprocal/sqrt, integer (add shift,


population count), logical

Fujitsu
VP100/200

1982

133

8-256

32-1024

3: FP or integer add/logical,
multiply, divide

Hitachi
S810/820

1983

71

32

256

4: 2 integer add/logical,
1 multiply-add, and 1 multiply/
divide-add unit

Convex C-1

1985

10

128

4: multiply, add, divide, integer/


logical

NEC SX/2

1984

160

8 + 8192

256 variable

16: 4 integer add/logical, 4 FP


multiply/divide, 4 FP add,
4 shift

DLXV

1990

200

64

5: multiply, divide, add,


integer add, logical

Cray C-90

1991

240

128

8: FP add, FP multiply, FP reciprocal, integer add, 2 logical,


shift, population count/parity

Convex C-4

1994

135

16

128

3: each is full integer, logical,


and FP (including multiply-add)

NEC SX/4

1995

400

8 + 8192

256 variable

16: 4 integer add/logical, 4 FP


multiply/divide, 4 FP add,
4 shift

Cray J-90

1995

100

64

4: FP add, FP multiply, FP reciprocal, integer/logical

Cray T-90

1996

~500

128

8: FP add, FP multiply, FP reciprocal, integer add, 2 logical,


shift, population count/parity

Functional units

Load-store
units
1

Figura 1.3: Caractersticas de varias arquitecturas vectoriales.


f2 : Vj Vk Vi
Algunos ejemplos son: V1 = sin(V2 ) o V3 = V1 + V2 .
2. Vector-escalar: Son instrucciones en cuyos operandos interviene alg
un escalar y
el resultado es un vector. Si s es un escalar son las instrucciones que siguen el
siguiente tipo de funcion:
f3 : d Vi Vj
Un ejemplo es el producto escalar, que el resultado es un vector tras multiplicar el
vector origen por el escalar elemento a elemento.
3. Vector-memoria: Suponiendo que M es el comienzo de un vector en memoria,
se tienen las instrucciones de carga y almacenamiento de un vector:
f4 : M V
f5 : V M

Carga del vector


Almacenamiento del vector

4. Reducci
on de vectores: Son instrucciones cuyos operandos son vectores y el
resultado es un escalar, por eso se llaman de reduccion. Los tipos de funciones que
describen estas instrucciones son los siguientes:
f6 : Vi sj
Ingeniera Informatica

Universidad de Valencia

Procesadores vectoriales
f7 : Vi Vj sk

El maximo,P
la suma, la media, etc., son ejemplos de f6 , mientras que el producto
punto (s = ni=1 ai bi ) es un ejemplo de f7 .
5. Reunir y Esparcir: Estas funciones sirven para almacenar/cargar vectores dispersos en memoria. Se necesitan dos vectores para reunir o esparcir el vector de/a
la memoria. Estas son las funciones para reunir y esparcir:
f8 : M V1 V0
f9 : V 1 V 0 M

Reunir
Esparcir

La operacion reunir toma de la memoria los elementos no nulos de un vector


disperso usando unos ndices. La operacion esparcir hace lo contrario, almacena
en la memoria un vector en un vector disperso cuyas entradas no nulas estan
indexadas. El registro vectorial V1 contiene los datos y el V0 los ndices de los
elementos no nulos.
6. Enmascaramiento: En estas instrucciones se utiliza un vector de mascara para
comprimir o expandir un vector a un vector ndice. La aplicacion que tiene lugar
es la siguiente:
f10 : V0 Vm V1

1.1.3

Ensamblador vectorial DLXV

En DLXV las operaciones vectoriales usan los mismos mnemotecnicos que las operaciones DLX, pero a
n adiendo la letra V (ADDV). Si una de las entradas es un escalar
se indicara a
n adiendo el sufijo SV (ADDSV). La figura 1.4 muestra las instrucciones
vectoriales del DLXV.
Ejemplo: el bucle DAXPY
Existe un bucle tpico para evaluar sistemas vectoriales y multiprocesadores que consiste
en realizar la operacion:
Y =aX +Y
donde X e Y son vectores que residen inicialmente en memoria, mientras que a es
un escalar. A este bucle, que es bastante conocido, se le llama SAXPY o DAXPY
dependiendo de si la operacion se realiza en simple o doble precision. A esta operacion
nos referiremos a la hora de hacer calculos de rendimiento y poner ejemplos. Estos bucles
forman el bucle interno del benchmark Linpack. (SAXPY viene de single-precision aX
plus Y; DAXPY viene de double-precision aX plus Y.) Linpack es un conjunto de
rutinas de algebra lineal, y rutinas para realizar el metodo de eliminacion de Gauss.
Para los ejemplos que siguen vamos a suponer que el n
umero de elementos, o longitud, de un registro vectorial coincide con la longitud de la operacion vectorial en la
que estamos interesados. Mas adelante se estudiara el caso en que esto no sea as.
Resulta interesante, para las explicaciones que siguen, dar los programas en ensamblador para realizar el calculo del bucle DAXPY. El siguiente programa sera el codigo
escalar utilizando el juego de instrucciones DLX:
Ingeniera Informatica

Universidad de Valencia

1.1 Procesador vectorial basico

Instruction

Operands

Function

ADDV
ADDSV

V1,V2,V3
V1,F0,V2

Add elements of V2 and V3, then put each result in V1.


Add F0 to each element of V2, then put each result in V1.

SUBV
SUBVS
SUBSV

V1,V2,V3
V1,V2,F0
V1,F0,V2

Subtract elements of V3 from V2, then put each result in V1.


Subtract F0 from elements of V2, then put each result in V1.
Subtract elements of V2 from F0, then put each result in V1.

MULTV
MULTSV

V1,V2,V3
V1,F0,V2

Multiply elements of V2 and V3, then put each result in V1.


Multiply F0 by each element of V2, then put each result in V1.

DIVV
DIVVS
DIVSV

V1,V2,V3
V1,V2,F0
V1,F0,V2

Divide elements of V2 by V3, then put each result in V1.


Divide elements of V2 by F0, then put each result in V1.
Divide F0 by elements of V2, then put each result in V1.

LV

V1,R1

Load vector register V1 from memory starting at address R1.

SV

R1,V1

Store vector register V1 into memory starting at address R1.

LVWS

V1,(R1,R2)

Load V1 from address at R1 with stride in R2, i.e., R1+i R2.

SVWS

(R1,R2),V1

Store V1 from address at R1 with stride in R2, i.e., R1+i R2.

LVI

V1,(R1+V2)

Load V1 with vector whose elements are at R1+V2(i), i.e., V2 is an index.

SVI

(R1+V2),V1

Store V1 to vector whose elements are at R1+V2(i), i.e., V2 is an index.

CVI

V1,R1

Create an index vector by storing the values 0, 1 R1, 2 R1,...,63 R1


into V1.

S--V
S--SV

V1,V2
F0,V1

Compare the elements (EQ, NE, GT, LT, GE, LE) in V1 and V2. If condition is true,
put a 1 in the corresponding bit vector; otherwise put 0. Put resulting bit vector in
vector-mask register (VM). The instruction S--SV performs the same compare but
using a scalar value as one operand.

POP

R1,VM

Count the 1s in the vector-mask register and store count in R1.

MOVI2S
MOVS2I

VLR,R1
R1,VLR

Move contents of R1 to the vector-length register.


Move the contents of the vector-length register to R1.

MOVF2S
MOVS2F

VM,F0
F0,VM

Move contents of F0 to the vector-mask register.


Move contents of vector-mask register to F0.

Set the vector-mask register to all 1s.

CVM

Figura 1.4: Instrucciones vectoriales del DLXV.


LD
ADDI
loop:
LD
MULTD
LD
ADDD
SD
ADDI
ADDI
SUB
BNZ

F0,a
R4,Rx,#512

;
ultima direcci
on a cargar

F2,0(Rx)
F2,F0,F2
F4,0(Ry)
F4,F2,F4
0(Ry),F4
Rx,Rx,#8
Ry,Ry,#8
R20,R4,Rx
R20,loop

;
;
;
;
;
;
;
;
;

carga X(i) en un registro


a.X(i)
carga Y(i) en un registro
a.X(i)+Y(i)
almacena resultado en Y(i)
incrementa el
ndice de X
incrementa el
ndice de Y
calcula l
mite
comprueba si fin.

El programa correspondiente en una arquitectura vectorial, como la DLXV, sera


de la siguiente forma:
LD
LV
MULTSV
LV
ADDV
SV

F0,a
V1,Rx
V2,F0,V1
V3,Ry
V4,V2,V3
Ry,V4

;
;
;
;
;
;

carga escalar a
carga vector X
a*X(i)
carga vector Y
suma
almacena el resultado

De los codigos anteriores se desprenden dos cosas. Por un lado la maquina vectorial
reduce considerablemente el n
umero de instrucciones a ejecutar, ya que se requieren
Ingeniera Informatica

Universidad de Valencia

Procesadores vectoriales

solo 6 frente a casi las 600 del bucle escalar. Por otro lado, en la ejecucion escalar, debe
bloquearse la suma, ya que comparte datos con la multiplicacion previa; en la ejecucion
vectorial, tanto la multiplicacion como la suma son independientes y, por tanto, no se
bloquea el cauce durante la ejecucion de cada instruccion sino entre una instruccion y la
otra, es decir, una sola vez. Estos bloqueos se pueden eliminar utilizando segmentacion
software o desarrollando el bucle, sin embargo, el ancho de banda de las instrucciones
sera mucho mas alto sin posibilidad de reducirlo.

1.1.4

Tiempo de ejecuci
on vectorial

Tres son los factores que influyen en el tiempo de ejecucion de una secuencia de operaciones vectoriales:
La longitud de los vectores sobre los que se opera.
Los riesgos estructurales entre las operaciones.
Las dependencias de datos.
Dada la longitud del vector y la velocidad de inicializacion, que es la velocidad a
la cual una unidad vectorial consume nuevos operandos y produce nuevos resultados,
podemos calcular el tiempo para una instruccion vectorial. Lo normal es que esta
velocidad sea de uno por ciclo del reloj. Sin embargo, algunos supercomputadores
producen 2 o mas resultados por ciclo de reloj, y otros, tienen unidades que pueden no
estar completamente segmentadas. Por simplicidad se supondra que esta velocidad es
efectivamente la unidad.
Para simplificar la discusion del tiempo de ejecucion se introduce la nocion de convoy,
que es el conjunto de instrucciones vectoriales que podran potencialmente iniciar su
ejecucion en el mismo ciclo de reloj. Las instrucciones en un convoy no deben incluir
ni riesgos estructurales ni de datos (aunque esto se puede relajar mas adelante); si
estos riesgos estuvieran presentes, las instrucciones potenciales en el convoy habra
que serializarlas e inicializarlas en convoyes diferentes. Para simplificar diremos que
las instrucciones de un convoy deben terminar de ejecutarse antes que cualquier otra
instruccion, vectorial o escalar, pueda empezar a ejecutarse. Esto se puede relajar
utilizando un metodo mas complejo de lanzar instrucciones.
Junto con la nocion de convoy esta la de toque o campanada (chime) que puede ser
usado para evaluar el rendimiento de una secuencia de vectores formada por convoyes.
Un toque o campanada es una medida aproximada del tiempo de ejecucion para una
secuencia de vectores; la medida de la campanada es independiente de la longitud del
vector. Por tanto, para una secuencia de vectores que consiste en m convoyes se ejecuta
en m campanadas, y para una longitud de vector de n, sera aproximadamente n m
ciclos de reloj. Esta aproximacion ignora algunas sobrecargas sobre el procesador que
ademas dependen de la longitud del vector. Por consiguiente, la medida del tiempo en
campanadas es una mejor aproximacion para vectores largos. Se usara esta medida, en
vez de los periodos de reloj, para indicar explcitamente que ciertas sobrecargas estan
siendo ignoradas.
Para poner las cosas un poco mas claras, analicemos el siguiente codigo y extraigamos de el los convoyes:
LD
F0,a
LV
V1,Rx
MULTSV V2,F0,V1

; carga el escalar en F0
; carga vector X
; multiplicaci
on vector-escalar

Ingeniera Informatica

Universidad de Valencia

1.1 Procesador vectorial basico


LV
ADDV
SV

V3,Ry
V4,V2,V3
Ry,V4

; carga vector Y
; suma vectorial
; almacena el resultado.

Dejando de lado la primera instruccion, que es puramente escalar, el primer convoy


lo ocupa la primera instruccion vectorial que es LV. La MULTSV depende de la primera
por eso no puede ir en el primer convoy, en cambio, la siguiente LV s que puede. ADDV
depende de esta LV por tanto tendra que ir en otro convoy, y SV depende de esta, as
que tendra que ir en otro convoy aparte. Los convoyes seran por tanto:
1. LV
2. MULTSV
LV
3. ADDV
4. SV
Como esta secuencia esta formada por 4 convoyes requerira 4 campanadas para su
ejecucion.
Esta aproximacion es buena para vectores largos. Por ejemplo, para vectores de 64
elementos, el tiempo en campanadas sera de 4, de manera que la secuencia tomara
unos 256 ciclos de reloj. La sobrecarga de eventualmente lanzar el convoy 2 en dos
ciclos diferentes sera peque
n a en comparacion a 256.
Tiempo de arranque vectorial y tasa de inicializaci
on
La fuente de sobrecarga mas importante, no considerada en el modelo de campanadas,
es el tiempo de arranque vectorial. El tiempo de arranque viene de la latencia del cauce
de la operacion vectorial y esta determinada principalmente por la profundidad del
cauce en relacion con la unidad funcional empleada. El tiempo de arranque incrementa
el tiempo efectivo en ejecutar un convoy en mas de una campanada. Ademas, este
tiempo de arranque retrasa la ejecucion de convoyes sucesivos. Por lo tanto, el tiempo
necesario para la ejecucion de un convoy viene dado por el tiempo de arranque y la
longitud del vector. Si la longitud del vector tendiera a infinito, entonces el tiempo de
arranque sera despreciable, pero lo normal es que el tiempo de arranque sea de 6 a 12
ciclos, lo que significa un porcentaje alto en vectores tpicos que como mucho rondaran
los 64 elementos o ciclos.
Operation

Start-up penalty

Vector add

Vector multiply

Vector divide

20

Vector load

12

Figura 1.5: Penalizacion por el tiempo de arranque en el DLXV.


Siguiendo con el ejemplo mostrado anteriormente, supongamos que cargar y salvar
tienen un tiempo de arranque de 12 ciclos, la multiplicacion 7 y la suma 6 tal y como se
desprende de la figura 1.5. Las sumas de los arranques de cada convoy para este ejemplo
sera 12+12+6+12=42, como estamos calculando el n
umero de campanadas reales para
Ingeniera Informatica

Universidad de Valencia

10

Procesadores vectoriales

vectores de 64 elementos, la division 42/64=0.65 da el n


umero de campanadas totales,
que sera entonces 4.65, es decir, el tiempo de ejecucion teniendo en cuenta la sobrecarga
de arranque es 1.16 veces mayor. En la figura 1.6 se muestra el tiempo en que se inicia
cada instruccion as como el tiempo total para su ejecucion en funcion de n que es el
n
umero de elementos del vector.
Convoy
1. LV
2. MULTSV LV

Starting time

First-result time

Last-result time

12

11 + n

12 + n

12 + n + 12

23 + 2n

3. ADDV

24 + 2n

24 + 2n + 6

29 + 3n

4. SV

30 + 3n

30 + 3n + 12

41 + 4n

Figura 1.6: Tiempos de arranque y del primer y u


ltimo resultados para los convoys 1-4.
El tiempo de arranque de una instruccion es tpicamente la profundidad del cauce
de la unidad funcional que realiza dicha instruccion. Si lo que se quiere es poder lanzar
una instruccion por ciclo de reloj (tasa de inicializacion igual a uno), entonces

Tiempo total de ejecucion de la unidad


Profundidad del cauce =
(1.1)
Periodo de reloj
Por ejemplo, si una operacion necesita 10 ciclos de reloj para completarse, entonces
hace falta un cauce con una profundidad de 10 para que se pueda inicializar una instruccion por cada ciclo de reloj. Las profundidades de las unidades funcionales varan
ampliamente (no es raro ver cauces de profundidad 20) aunque lo normal es que tengan
profundidades entre 4 y 8 ciclos.

1.1.5

Unidades de carga/almacenamiento vectorial

El comportamiento de la unidad de carga/almacenamiento es mas complicado que el


de las unidades aritmeticas. El tiempo de arranque para una carga es el tiempo para
coger la primera palabra de la memoria y guardarla en un registro. Si el resto del vector
se puede coger sin paradas, la tasa de inicializacion es la misma que la velocidad a la
que las nuevas palabras son tradas y almacenadas. Al contrario que en las unidades
funcionales, la tasa de inicializacion puede no ser necesariamente una instruccion por
ciclo.
Normalmente, el tiempo de arranque para las unidades de carga/almacenamiento
es algo mayor que para las unidades funcionales, pudiendo llegar hasta los 50 ciclos.
Tpicamente, estos valores rondan entre los 9 y los 17 ciclos (Cray 1 y Cray X-MP)
Para conseguir una tasa (o velocidad) de inicializacion de una palabra por ciclo,
el sistema de memoria debe ser capaz de producir o aceptar esta cantidad de datos.
Esto se puede conseguir mediante la creacion de bancos de memoria m
ultiples como se
explica en la seccion 1.2. Teniendo un n
umero significativo de bancos se puede conseguir
acceder a la memoria por filas o por columnas de datos.
El n
umero de bancos en la memoria del sistema para las unidades de carga y almacenamiento, as como la profundidad del cauce en unidades funcionales son de alguna
Ingeniera Informatica

Universidad de Valencia

1.2 Memoria entrelazada o intercalada

11

manera equivalentes, ya que ambas determinan las tasas de inicializacion de las operaciones utilizando estas unidades. El procesador no puede acceder a un banco de
memoria mas deprisa que en un ciclo de reloj. Para los sistemas de memoria que soportan m
ultiples accesos vectoriales simultaneos o que permiten accesos no secuenciales en
la carga o almacenamiento de vectores, el n
umero de bancos de memoria debera ser
mas grande que el mnimo, de otra manera existiran conflictos en los bancos.

1.2

Memoria entrelazada o intercalada

La mayor parte de esta seccion se encuentra en el [Hwa93], aunque se puede encontrar


una peque
n a parte en el [HP96] en el captulo dedicado a los procesadores vectoriales.
Para poder salvar el salto de velocidad entre la CPU/cache y la memoria principal
realizada con modulos de RAM, se presenta una tecnica de entrelazado que permite el
acceso segmentado a los diferentes modulos de memoria paralelos.
Vamos a suponer que la memoria principal se encuentra construida a partir de varios
modulos. Estos modulos de memoria se encuentran normalmente conectados a un bus
del sistema, o a una red de conmutadores, a la cual se conectan otros dispositivos del
sistema como procesadores o subsistemas de entrada/salida.
Cuando se presenta una direccion en un modulo de memoria esta devuelve la palabra
correspondiente. Es posible presentar diferentes direcciones a diferentes modulos de
memoria de manera que se puede realizar un acceso paralelo a diferentes palabras de
memoria. Ambos tipos de acceso, el paralelo y el segmentado, son formas paralelas
practicadas en una organizacion de memoria paralela.
Consideremos una memoria principal formada por m = 2a modulos, cada uno con
w = 2b palabras o celdas de memoria. La capacidad total de la memoria es m w = 2a+b
palabras. A estas palabras se les asignan direcciones de forma lineal. Las diferentes
formas en las que se asignan linealmente las direcciones producen diferentes formas de
organizar la memoria.
Aparte de los accesos aleatorios, la memoria principal es accedida habitualmente
mediante bloques de direcciones consecutivas. Los accesos en bloque son necesarios
para traerse una secuencia de instrucciones o para acceder a una estructura lineal de
datos, etc. En un sistema basado en cache la longitud del bloque suele corresponderse
con la longitud de una lnea en la cache, o con varias lneas de cache. Tambien en
los procesadores vectoriales el acceso a la memoria tiene habitualmente una estructura
lineal, ya que los elementos de los vectores se encuentran consecutivos. Por todo esto, resulta preferible dise
n ar la memoria principal para facilitar el acceso en bloque a
palabras contiguas.
La figura 1.7 muestra dos formatos de direcciones para realizar una memoria entrelazada. El entrelazado de orden bajo (figura 1.7(a)) reparte las localizaciones contiguas
de memoria entre los m modulos de forma horizontal. Esto implica que los a bits de
orden bajo de la direccion se utilizan para identificar el modulo de memoria. Los b bits
de orden mas alto forman la direccion de la palabra dentro de cada modulo. Hay que
hacer notar que la misma direccion de palabra esta siendo aplicada a todos los modulos
de forma simultanea. Un decodificador de direcciones se emplea para distribuir la seleccion de los modulos. Este esquema no es bueno para tolerancia a fallos, ya que en
caso de fallo de un modulo toda la memoria queda inutilizable.
Ingeniera Informatica

Universidad de Valencia

12

Procesadores vectoriales

El entrelazado de orden alto (figura 1.7(b)) utiliza los a bits de orden alto como
selector de modulo, y los b bits de orden bajo como la direccion de la palabra dentro
de cada modulo. Localizaciones contiguas en la memoria estan asignadas por tanto a
un mismo modulo de memoria. En un ciclo de memoria, solo se accede a una palabra
del modulo. Por lo tanto, el entrelazado de orden alto no permite el acceso en bloque a
posiciones contiguas de memoria. Este esquema viene muy bien para tolerancia a fallos.
Por otro lado, el entrelazado de orden bajo soporta el acceso de bloque de forma
segmentada. A no ser que se diga otra cosa, se supondra para el resto del captulo que
la memoria es del tipo entrelazado de orden bajo.

Decodificador
Direcciones

BDM
M0

0
m

Direccin
a
de memoria
Palabra
Mdulo
b
Buffer de
BDP direccin
de palabra

BDM
1
m+1

BDM
M1

m-1
2m-1

m(w-1)

m(w-1)+1

mw-1

BDM

BDM

BDM

Buffer de las
direcciones de
mdulo
M m-1

Buffer de
datos de memoria

Bus de datos

(a) Memoria de m vas entrelazada de orden bajo (esquema C de acceso


a memoria).

BDM

Decodificador
Direcciones
a

Direccin
de memoria
Mdulo Palabra
b
Buffer de
direccin BDP
de palabra

0
1

BDM
M0

w
w+1

BDM
M1

Buffer de las
direcciones de
mdulo

M m-1
(m-1)w
(m-1)w+1

w-1

2w-1

mw-1

BDM

BDM

BDM

Buffer de
datos de memoria

Bus de datos

(b) Memoria de m vas entrelazada de orden alto.

Figura 1.7: Dos organizaciones de memoria entrelazada con m = 2a modulos y w = 2a


palabras por modulo.
Ejemplo de memoria modular en un procesador vectorial
Supongamos que queremos captar un vector de 64 elementos que empieza en la direccion
136, y que un acceso a memoria supone 6 ciclos de reloj. Cuantos bancos de memoria
debemos tener para acceder a cada elemento en un u
nico ciclo de reloj? Con que
direccion se accede a estos bancos? Cuando llegaran los elementos a la CPU?.
Ingeniera Informatica

Universidad de Valencia

1.2 Memoria entrelazada o intercalada

13

Respuesta Con seis ciclos por acceso, necesitamos al menos seis bancos de memoria,
pero como queremos que el n
umero de bancos sea potencia de dos, elegiremos ocho
bancos. La figura 1.1 muestra las direcciones a las que se accede en cada banco en cada
periodo de tiempo.

Beginning
at clock no.

Bank
3

192

136

144

152

160

168

176

184

256

200

208

216

224

232

240

248

14

320

264

272

280

288

296

304

312

22

384

328

336

344

352

360

368

376

Tabla 1.1: Direcciones de memoria (en bytes) y momento en el cual comienza el acceso
a cada banco.
La figura 1.8 muestra la temporizacion de los primeros accesos a un sistema de ocho
bancos con una latencia de acceso de seis ciclos de reloj. Existen dos observaciones
importantes con respecto a la tabla 1.1 y la figura 1.8: La primera es que la direccion
exacta proporcionada por un banco esta muy determinada por los bits de menor orden;
sin embargo, el acceso inicial a un banco esta siempre entre las ocho primeras dobles
palabras de la direccion inicial. La segunda es que una vez se ha producido la latencia
inicial (seis ciclos en este caso), el patron es acceder a un banco cada n ciclos, donde n
es el n
umero total de bancos (n = 8 en este caso).
Deliver #
last#
8 words

Next access# Next access#


Memory# + deliver last# + deliver last#
8 words
8 words
access

Action
Time
0

14

22

62

70

Figura 1.8: Tiempo de acceso para las primeras 64 palabras de doble precision en una
lectura.

1.2.1

Acceso concurrente a memoria (acceso C)

Los accesos a los m modulos de una memoria se pueden solapar de forma segmentada.
Para esto, el ciclo de memoria (llamado ciclo mayor de memoria se subdivide en m
ciclos menores.
Sea el tiempo para la ejecucion del ciclo mayor y para el menor. Estos dos
tiempos se relacionan de la siguiente manera:
=

(1.2)

donde m es el grado de entrelazado. La temporizacion del acceso segmentado de 8 palabras contiguas en memoria se muestra en la figura 1.9. A este tipo de acceso concurrente
a palabras contiguas se le llama acceso C a memoria. El ciclo mayor es el tiempo
total necesario para completar el acceso a una palabra simple de un modulo. El ciclo
Ingeniera Informatica

Universidad de Valencia

14

Procesadores vectoriales

menor es el tiempo necesario para producir una palabra asumiendo la superposicion


de accesos de modulos de memoria sucesivos separados un ciclo menor .
Hay que hacer notar que el acceso segmentado al bloque de 8 palabras contiguas
esta emparedado entre otros accesos de bloque segmentados antes y despues del bloque
actual. Incluso a pesar de que el tiempo total de acceso del bloque es 2, el tiempo
efectivo de acceso de cada palabra es solamente al ser la memoria contiguamente
accedida de forma segmentada.

W7
W6
W5
W4
W3
W2
W1
W0

Ciclo mayor

=/m
m

Ciclo menor

Grado de entrelazado

Tiempo

Figura 1.9: Acceso segmentado a 8 palabras contiguas en una memoria de acceso C.

1.2.2

Acceso simult
aneo a memoria (acceso S)

La memoria entrelazada de orden bajo puede ser dispuesta de manera que permita
accesos simultaneos, o accesos S, tal y como se muestra en la figura 1.10.
Ciclo de bsqueda

Ciclo de acceso
Latch

Lectura
Escritura

Mdulo
0
Mdulo
1

(n-a) bits
de orden alto

Acceso a palabra
Multiplexor

Mdulo
m-1
a bits de orden bajo

Figura 1.10: Organizacion de acceso S para una memoria entrelazada de m vas.


Al final de cada ciclo de memoria, m = 2a palabras consecutivas son capturadas en
los buffers de datos de forma simultanea. Los a bits de orden bajo se emplean entonces
para multiplexar las m palabras hacia fuera, una por cada ciclo menor. Si se elige el
ciclo menor para que valga un 1/m de la duracion del ciclo mayor (Ec. 1.2), entonces
se necesitan dos ciclos de memoria para acceder a m palabras consecutivas.
Ingeniera Informatica

Universidad de Valencia

1.2 Memoria entrelazada o intercalada

15

Sin embargo, si la fase de acceso del u


ltimo acceso, se superpone con la fase de
b
usqueda del acceso actual, entonces son m palabras las que pueden ser accedidas en
un u
nico ciclo de memoria.

1.2.3

Memoria de acceso C/S

Una organizacion de memoria que permite los accesos de tipo C y tambien los de tipo
S se denomina memoria de acceso C/S. Este esquema de funcionamiento se muestra
en la figura 1.11, donde n buses de acceso se utilizan junto a m modulos de memoria
entrelazada conectados a cada bus. Los m modulos en cada bus son entrelazados de m
vas para permitir accesos C. Los n buses operan en paralelo para permitir los accesos
S. En cada ciclo de memoria, al menos m n palabras son capturadas si se emplean
completamente los n buses con accesos a memoria segmentados.
Procesadores
P(0)
P(1)

P(n-1)

Memorias
MC(0)
MC(1)

Interconexin

M(0,0)

M(0,1)

M(0,m-1)

Barra
Cruzada

M(1,0)

M(1,1)

M(1,m-1)

M(n-1,0)

M(n-1,1)

M(n-1,m-1)

MC(n-1)

Figura 1.11: Organizacion de acceso C/S.


La memoria C/S esta especialmente indicada para ser usada en configuraciones de
multiprocesadores vectoriales, ya que provee acceso segmentado en paralelo de un conjunto vectorial de datos con un alto ancho de banda. Una cache vectorial especialmente
dise
n ada es necesaria en el interior de cada modulo de proceso para poder garantizar
el movimiento suave entre la memoria y varios procesadores vectoriales.

1.2.4

Rendimiento de la memoria entrelazada y tolerancia a


fallos

Con la memoria pasa algo parecido que con los procesadores: no por poner m modulos
paralelos en el sistema de memoria se puede acceder m veces mas rapido. Existe un
modelo mas o menos emprico que da el aumento del ancho de banda por el hecho
de aumentar el n
umero de bancos de la memoria. Este modelo fue introducido por
Hellerman y da el ancho de banda B en funcion del n
umero de bancos m:

B = m0.56 m
Esta raz cuadrada da una estimacion pesimista del aumento de las prestaciones de
la memoria. Si por ejemplo se ponen 16 modulos en la memoria entrelazada, solo se
obtiene un aumento de 4 veces el ancho de banda. Este resultado lejano a lo esperado
viene de que en la memoria principal de los multiprocesadores los accesos entrelazados
se mezclan con los accesos simples o con los accesos de bloque de longitudes dispares.
Ingeniera Informatica

Universidad de Valencia

16

Procesadores vectoriales

Para los procesadores vectoriales esta estimacion no es realista, ya que las transacciones con la memoria suelen ser casi siempre vectoriales y, por tanto, pueden ser
facilmente entrelazadas.
En 1992 Cragon estimo el tiempo de acceso a una memoria entrelazada vectorial de
la siguiente manera: Primero se supone que los n elementos de un vector se encuentran consecutivos en una memoria de m modulos. A continuacion, y con ayuda de la
figura 1.9, no es difcil inferir que el tiempo que tarda en accederse a un vector de n
elementos es la suma de lo que tarda el primer elemento (), que tendra que recorrer
todo el cauce, y lo que tardan los (n 1) elementos restantes ((n 1)/m) que estaran
completamente encauzados. El tiempo que tarda un elemento (t1 ) se obtiene entonces
dividiendo lo que tarda el vector completo entre n:
+
t1 =

(n 1)

(n 1)
m n1

m1
m
= +
=
+
=
1+
n
n
nm
m n
n
m
n

Por lo tanto el tiempo medio t1 requerido para acceder a un elemento en la memoria


ha resultado ser:

m1
t1 =
1+
m
n
Cuando n (vector muy grande), t1 /m = tal y como se derivo en la
ecuacion (1.2). Ademas si m = 1, no hay memoria entrelazada y t1 = . La ecuacion
que se acaba de obtener anuncia que la memoria entrelazada se aprovecha del acceso
segmentado de los vectores, por lo tanto, cuanto mayor es el vector mas rendimiento se
obtiene.
Tolerancia a fallos
La division de la memoria en bancos puede tener dos objetivos: por un lado permite un
acceso concurrente lo que disminuye el acceso a la memoria (memoria entrelazada), por
otro lado se pueden configurar los modulos de manera que el sistema de memoria pueda
seguir funcionando en el caso de que alg
un modulo deje de funcionar. Si los modulos
forman una memoria entrelazada el tiempo de acceso sera menor pero el sistema no
sera tolerante a fallos, ya que al perder un modulo se pierden palabras en posiciones
salteadas en toda la memoria, con lo que resulta difcil seguir trabajando. Si por el
contrario los bancos se han elegido por bloques de memoria (entrelazado de orden alto)
en vez de palabras sueltas, en el caso en que falle un bloque lo programas podran seguir
trabajando con los bancos restantes aislandose ese bloque de memoria erroneo del resto.
En muchas ocasiones interesa tener ambas caractersticas a un tiempo, es decir, por
un lado interesa tener memoria entrelazada de orden bajo para acelerar el acceso a la
memoria, pero por otro interesa tambien una memoria entrelazada de orden alto para
tener la memoria dividida en bloques y poder seguir trabajando en caso de fallo de un
modulo o banco. Para estos casos en que se requiere alto rendimiento y tolerancia a
fallos se puede dise
n ar una memoria mixta que contenga modulos de acceso entrelazado,
y bancos para tolerancia a fallos.
La figura 1.12 muestra dos alternativas que combinan el entrelazado de orden alto
con el de orden bajo. Ambas alternativas ofrecen una mejora del rendimiento de la memoria junto con la posibilidad de tolerancia a fallos. En el primer ejemplo (figura 1.12a)
Ingeniera Informatica

Universidad de Valencia

1.2 Memoria entrelazada o intercalada

17

se muestra una memoria de cuatro modulos de orden bajo y dos bancos de memoria.
En el segundo ejemplo (figura 1.12b) se cuenta con el mismo n
umero de modulos pero
dispuestos de manera que hay un entrelazado de dos modulos y cuatro bancos de memoria. El primer ejemplo presenta un mayor entrelazado por lo que tendra un mayor
rendimiento que el segundo, pero tambien presenta menos bancos por lo que en caso
de fallo se pierde una mayor cantidad de memoria, aparte de que el da
n o que se puede
causar al sistema es mayor.

Figura 1.12: Dos organizaciones de memoria entrelazada usando 8 modulos: (a) 2


bancos y 4 modulos entrelazados, (b) 4 bancos y 2 modulos entrelazados.

Si la tolerancia a fallos es fundamental para un sistema, entonces hay que establecer


un compromiso entre el grado de entrelazado para aumentar la velocidad y el n
umero de
bancos para aumentar la tolerancia a fallos. Cada banco de memoria es independiente
de las condiciones de otros bancos y por tanto ofrece un mejor aislamiento en caso de
avera.
Ingeniera Informatica

Universidad de Valencia

18

Procesadores vectoriales

1.3

Longitud del vector y separaci


on de elementos

Esta seccion pretende dar respuesta a dos problemas que surgen en la vida real, uno
es que hacer cuando la longitud del vector es diferente a la longitud de los registros
vectoriales (por ejemplo 64 elementos), y la otra es como acceder a la memoria si los
elementos del vector no estan contiguos o se encuentran dispersos.

1.3.1

Control de la longitud del vector

La longitud natural de un vector viene determinada por el n


umero de elementos en los
registros vectoriales. Esta longitud, casi siempre 64, no suele coincidir muchas veces
con la longitud de los vectores reales del programa. Aun mas, en un programa real
se desconoce incluso la longitud de cierto vector u operacion incluso en tiempo de
compilacion. De hecho, un mismo trozo de codigo puede requerir diferentes longitudes
en funcion de parametros que cambien durante la ejecucion de un programa. El siguiente
ejemplo en Fortran muestra justo este caso:
10

do 10 i=1,n
Y(i)=a*X(i)+Y(i)

La solucion de estos problemas es la creacion de un registro de longitud vectorial VLR


(Vector-Length register). El VLR controla la longitud de cualquier operacion vectorial
incluyendo las de carga y almacenamiento. De todas formas, el vector en el VLR no
puede ser mayor que la longitud de los registros vectoriales. Por lo tanto, esto resuelve
el problema siempre que la longitud real sea menor que la longitud vectorial maxima
MVL (Maximum Vector Length) definida por el procesador.
Para el caso en el que la longitud del vector real sea mayor que el MVL se utiliza
una tecnica denominada seccionamiento (strip mining). El seccionamiento consiste en la
generacion de codigo de manera que cada operacion vectorial se realiza con un tama
no
inferior o igual que el del MVL. Esta tecnica es similar a la de desenrollamiento de
bucles, es decir, se crea un bucle que consiste en varias iteraciones con un tama
n o como
el del MVL, y luego otra iteracion mas que sera siempre menor que el MVL. La version
seccionada del bucle DAXPY escrita en Fortran se da a continuacion:
low=1
VL=(n mod MVL)
do 1 j=0,(n/MVL)
do 10 i=low,low+VL-1
Y(i)=a*X(i)+Y(i)
10
continue
low=low+VL
VL=MVL
1 continue

/*
/*
/*
/*

Para encontrar el pedazo aparte */


Bucle externo
*/
Ejecuta VL veces
*/
Operaci
on principal
*/

/* Comienzo del vector siguiente


/* Pone la longitud al m
aximo */

*/

En este bucle primero se calcula la parte que sobra del vector (que se calcula con el
modulo de n y MVL) y luego ejecuta ya las veces que sea necesario con una longitud de
vector maxima. O sea, el primer vector tiene una longitud de (n mod MVL) y el resto
tiene una longitud de MVL tal y como se muestra en la figura 1.13. Normalmente los
compiladores hacen estas cosas de forma automatica.
Junto con la sobrecarga por el tiempo de arranque, hay que considerar la sobrecarga
por la introduccion del bucle del seccionamiento. Esta sobrecarga por seccionamiento,
Ingeniera Informatica

Universidad de Valencia

1.3 Longitud del vector y separacion de elementos


Value of j

12

Range of i

1..m

(m+1)..
m+MVL

(m+
MVL+1)
.. m+2 *
MVL

19

...

...

n/MVL

(m+2 *
MVL+1)
..m+3 *
MVL

...

...

(n-MVL
+1).. n

Figura 1.13: Un vector de longitud arbitraria procesado mediante seccionamiento. Todos los bloques menos el primero son de longitud MVL. En esta figura, la variable m
se usa en lugar de la expresion (n mod M V L).
que aparece de la necesidad de reiniciar la secuencia vectorial y asignar el VLR, efectivamente se suma al tiempo de arranque del vector, asumiendo que el convoy no se
solapa con otras instrucciones. Si la sobrecarga de un convoy es de 10 ciclos, entonces
la sobrecarga efectiva por cada 64 elementos se incrementa en 10, o lo que es lo mismo
0.15 ciclos por elemento del vector real.

1.3.2

C
alculo del tiempo de ejecuci
on vectorial

Con todo lo visto hasta ahora se puede dar un modelo sencillo para el calculo del tiempo
de ejecucion de las instrucciones en un procesador vectorial. Repasemos estos costes:
1. Por un lado tenemos el n
umero de convoyes en el bucle que nos determina el
n
umero de campanadas. Usaremos la notacion Tcampanada para indicar el tiempo
en campanadas.
2. La sobrecarga para cada secuencia seccionada de convoyes. Esta sobrecarga consiste en el coste de ejecutar el codigo escalar para seccionar cada bloque, Tbucle ,
mas el coste de arranque para cada convoy, Tarranque .
3. Tambien podra haber una sobrecarga fija asociada con la preparacion de la secuencia vectorial la primera vez, pero en procesadores vectoriales modernos esta
sobrecarga se ha convertido en algo muy peque
n o por lo que no se considerara en
la expresion de carga total. En algunos libros donde todava aparece este tiempo
se le llama Tbase .
Con todo esto se puede dar una expresion para calcular el tiempo de ejecucion para
una secuencia vectorial de operaciones de longitud n, que llamaremos Tn :
l n m
(Tbucle + Tarranque ) + n Tcampanada
(1.3)
Tn =
MVL
Los valores para Tarranque , Tbucle y Tcampanada dependen del procesador y del compilador
que se utilice. Un valor tpico para Tbucle es 15 (Cray 1). Podra parecer que este tiempo
debera ser mayor, pero lo cierto es que muchas de las operaciones de esta sobrecarga
se solapan con las instrucciones vectoriales.
Para aclarar todo esto veamos un ejemplo. Se trata de averiguar el tiempo que
tarda un procesador vectorial en realizar la operacion A = B s, donde s es un escalar,
A y B son vectores con una longitud de 200 elementos. Lo que se hace primero es
ver el codigo en ensamblador que realiza esta operacion. Para ello supondremos que las
direcciones de A y B son inicialmente Ra y Rb, y que s se encuentra en Fs. Supondremos
que R0 siempre contiene 0 (DLX). Como 200 mod 64=8, la primera iteracion del bucle
seccionado se realizara sobre un vector de longitud 8, y el resto con una longitud de
Ingeniera Informatica

Universidad de Valencia

20

Procesadores vectoriales

64 elementos. La direccion del byte de comienzo del segmento siguiente de cada vector
es ocho veces la longitud del vector. Como la longitud del vector es u ocho o 64, se
incrementa el registro de direccion por 8 8 = 64 despues del primer segmento, y por
8 64 = 512 para el resto. El n
umero total de bytes en el vector es 8 200 = 1600, y se
comprueba que ha terminado comparando la direccion del segmento vectorial siguiente
con la direccion inicial mas 1600. A continuacion se da el codigo:

LOOP:

ADDI
ADD
ADDI
MOVI2S
ADDI
ADDI
LV
MULTVS
SV
ADD
ADD
ADDI
MOVI2S
SUB
BNZ

R2,R0,#1600
R2,R2,Ra
R1,R0,#8
VLR,R1
R1,R0,#64
R3,R0,#64
V1,Rb
V2,V1,Fs
Ra,V2
Ra,Ra,R1
Rb,Rb,R1
R1,R0,#512
VLR,R3
R4,R2,Ra
R4,LOOP

;
;
;
;
;
;
;
;
;
;
;
;
;
;
;

Bytes en el vector
Final del vector A
Longitud del 1er segmento
Carga longitud del vector en VLR
Longitud del 1er segmento
Longitud del resto de segmentos
Carga B
Vector * escalar
Guarda A
Direcci
on del siguiente segmento de A
Direcci
on del siguiente segmento de B
Byte offset del siguiente segmento
Longitud 64 elementos
Final de A?
sino, repite.

Las tres instrucciones vectoriales del bucle dependen unas de otras y deben ir en
tres convoyes separados, por lo tanto Tcampanada = 3. El tiempo del bucle ya habamos
dicho que ronda los 15 ciclos. El valor del tiempo de arranque sera la suma de tres
cosas:
El tiempo de arranque de la instruccion de carga, que supondremos 12 ciclos.
El tiempo de arranque de la multiplicacion, 7 ciclos.
El tiempo de arranque del almacenamiento, otros 12 ciclos.
Por lo tanto obtenemos un valor Tarranque = 12 + 7 + 12 = 31 ciclos de reloj. Con todo
esto, y aplicando la ecuacion (1.3), se obtiene un tiempo total de proceso de T200 = 784
ciclos de reloj. Si dividimos por el n
umero de elementos obtendremos el tiempo de
ejecucion por elemento, es decir, 784/200 = 3.9 ciclos de reloj por elemento del vector.
Comparado con Tcampanada , que es el tiempo sin considerar las sobrecargas, vemos que
efectivamente la sobrecarga puede llegar a tener un valor significativamente alto.
Resumiendo las operaciones realizadas se tiene el siguiente proceso hasta llegar al
resultado final:
l n m
(Tloop + Tarranque ) + n Tcampanada
Tn =
MV L
T200 = 4 (15 + Tstart ) + 200 3
T200 = 60 + (4 Tstart ) + 600 = 660 + (4 Tstart )
Tstart=12+7+12=31
T200 = 660 + 4 31 = 784
La figura 1.14 muestra la sobrecarga y el tiempo total de ejecucion por elemento
del ejemplo que estamos considerando. El modelo que solo considera las campanadas
tendra un coste de 3 ciclos, mientras que el modelo mas preciso que incorpora la
sobrecarga a
n ade 0.9 a este valor.
Ingeniera Informatica

Universidad de Valencia

1.3 Longitud del vector y separacion de elementos

21

Ciclos de reloj por elemento

Tiempo total por elemento

Sobrecarga total por elemento

20

40

60

80

100
120
Elementos en el vector

140

160

180

200

Figura 1.14: Tiempo de ejecucion por elemento en funcion de la longitud del vector.

1.3.3

Separaci
on de elementos en el vector

El otro problema que se presenta en la programacion real es que la posicion en memoria


de elementos adyacentes no siempre son contiguas. Por ejemplo, consideremos el codigo
tpico para multiplicacion de matrices:
do 10 i=1,100
do 10 j=1,100
A(i,j)=0.0
do 10 k=1,100
10
A(i,j)=A(i,j)+B(i,k)*C(k,j)

En la sentencia con etiqueta 10, se puede vectorizar la multiplicacion de cada fila


de B con cada columna de C, y seccionar el bucle interior usando k como variable
ndice. Cuando una matriz se ubica en memoria, se lineariza organizandola en filas
o en columnas. El almacenamiento por filas, utilizado por muchos lenguajes menos
el Fortran, consiste en asignar posiciones consecutivas a elementos consecutivos en la
fila, haciendo adyacentes los elementos B(i, j) y B(i, j + 1). El almacenamiento por
columnas, utilizado en Fortran, hace adyacentes los elementos B(i, j) y B(i + 1, j).
Suponiendo que utilizamos el almacenamiento por columnas de Fortran nos encontramos con que los accesos a la matriz B no son adyacentes en memoria sino que se
encuentran separados por una fila completa de elementos. En este caso, los elementos de B que son accedidos en el lazo interior, estan separados por el tama
n o de fila
multiplicado por 8 (n
umero de bytes por elemento) lo que hace un total de 800 bytes.
A esta distancia en memoria entre elementos consecutivos se le llama separaci
on
(stride). Con el ejemplo que estamos viendo podemos decir que los elementos de C
Ingeniera Informatica

Universidad de Valencia

22

Procesadores vectoriales

tienen una separacion de 1, (1 palabra doble, 8 bytes), mientras que la matriz B tiene
una separacion de 100 (100 palabras dobles, 800 bytes).
Una vez cargados estos elementos adyacentes en el registro vectorial, los elementos
son logicamente contiguos. Por todo esto, y para aumentar el rendimiento de la carga
y almacenamiento de vectores con elementos separados, resulta interesante disponer de
instrucciones que tengan en cuenta la separacion entre elementos contiguos de un vector.
La forma de introducir esto en el lenguaje ensamblador es mediante la incorporacion
de dos instrucciones nuevas, una de carga y otra de almacenamiento, que tengan en
cuenta no solo la direccion de comienzo del vector, como hasta ahora, sino tambien el
paso o la separacion entre elementos. En DLXV, por ejemplo, existen las instrucciones
LVWS para carga con separacion, y SVWS para almacenamiento con separacion. As, la
instruccion LVWS V1,(R1,R2) carga en V1 lo que hay a partir de R1 con un paso o
separacion de elementos de R2, y SVWS (R1,R2),V1 guarda los elementos del vector V1
en la posicion apuntada por R1 con paso R2.
Naturalmente, el que los elementos no esten separados de forma unitaria crea complicaciones en la unidad de memoria. Se haba comprobado que una operacion memoriaregistro vectorial poda proceder a velocidad completa si el n
umero de bancos en memoria era al menos tan grande el tiempo de acceso a memoria en ciclos de reloj. Sin
embargo, para determinadas separaciones entre elementos, puede ocurrir que accesos
consecutivos se realicen al mismo banco, llegando incluso a darse el caso de que todos
los elementos del vector se encuentren en el mismo banco. A esta situacion se le llama
conflicto del banco de memoria y hace que cada carga necesite un mayor tiempo de
acceso a memoria. El conflicto del banco de memoria se presenta cuando se le pide al
mismo banco que realice un acceso cuando el anterior a
un no se haba completado. Por
consiguiente, la condicion para que se produzca un conflicto del banco de memoria sera:
Mn. com
un mult.(separacion, n
um. modulos)
< Latencia acceso a memoria
Separacion
Los conflictos en los modulos no se presentan si la separacion entre los elementos y
el n
umero de bancos son relativamente primos entre s, y ademas hay suficientes bancos
para evitar conflictos en el caso de separacion unitaria. El aumento de n
umero de
bancos de memoria a un n
umero mayor del mnimo, para prevenir detenciones con una
separacion 1, disminuira la frecuencia de detenciones para las demas separaciones. Por
ejemplo, con 64 bancos, una separacion de 32 parara cada dos accesos en lugar de cada
acceso. Si originalmente tuviesemos una separacion de 8 con 16 bancos, parara cada
dos accesos; mientras que con 64 bancos, una separacion de 8 parara cada 8 accesos. Si
tenemos acceso a varios vectores simultaneamente, tambien se necesitaran mas bancos
para prevenir conflictos. La mayora de supercomputadores vectoriales actuales tienen
como mnimo 64 bancos, y algunos llegan a 512.
Veamos un ejemplo. Supongamos que tenemos 16 bancos de memoria con un tiempo
de acceso de 12 ciclos de reloj. Calcular el tiempo que se tarda en leer un vector de 64
elementos separados unitariamente. Repetir el calculo suponiendo que la separacion es
de 32. Como el n
umero de bancos es mayor que la latencia, la velocidad de acceso sera
de elemento por ciclo, por tanto 64 ciclos, pero a esto hay que a
n adirle el tiempo de
arranque que supondremos 12, por tanto la lectura se realizara en 12 + 64 = 76 ciclos de
reloj. La peor separacion es aquella en la que la separacion sea un m
ultiplo del n
umero
de bancos, como en este caso que tenemos una separacion de 32 y 16 bancos. En este
caso siempre se accede al mismo banco con lo que cada acceso colisiona con el anterior,
Ingeniera Informatica

Universidad de Valencia

1.4 Mejora del rendimiento de los procesadores vectoriales

23

esto nos lleva a un tiempo de acceso de 12 ciclos por elemento y un tiempo total de
12 64 = 768 ciclos de reloj.

1.4
1.4.1

Mejora del rendimiento de los procesadores vectoriales


Encadenamiento de operaciones vectoriales

Hasta ahora, se haban considerado separadas, y por tanto en convoyes diferentes,


instrucciones sobre vectores que utilizaran el mismo o los mismos registros vectoriales.
Este es el caso, por ejemplo de dos instrucciones como
MULTV
ADDV

V1,V2,V3
V4,V1,V5

Si se trata en este caso al vector V1 no como una entidad, sino como una serie de
elementos, resulta sencillo entender que la operacion de suma pueda iniciarse unos ciclos
despues de la de multiplicacion, y no despues de que termine, ya que los elementos que la
suma puede ir necesitando ya los ha generado la multiplicacion. A esta idea, que permite
solapar dos instrucciones, se le llama encadenamiento. El encadenamiento permite que
una operacion vectorial comience tan pronto como los elementos individuales de su
operando vectorial fuente esten disponibles, es decir, los resultados de la primera unidad
funcional de la cadena se adelantan a la segunda unidad funcional. Naturalmente deben
ser unidades funcionales diferentes, de lo contrario surge un conflicto temporal.
Si las unidades estan completamente segmentadas, basta retrasar el comienzo de la
siguiente instruccion durante el tiempo de arranque de la primera unidad. El tiempo
total de ejecucion para la secuencia anterior sera:
Longitud del vector + Tiempo de arranque suma + Tiempo de arranque multiplicacion
La figura 1.15 muestra los tiempos de una version de ejecucion no encadenada y
de otra encadenada del par de instrucciones anterior suponiendo una longitud de 64
elementos. El tiempo total de la ejecucion encadenada es de 77 ciclos de reloj que es
sensiblemente inferior a los 145 ciclos de la ejecucion sin encadenar. Con 128 operaciones
en punto flotante realizadas en ese tiempo, se obtiene 1.7 FLOP por ciclo de reloj,
mientras que con la version no encadenada la tasa sera de 0.9 FLOP por ciclo de reloj.

1.4.2

Sentencias condicionales

Se puede comprobar mediante programas de test, que los niveles de vectorizacion en


muchas aplicaciones no son muy altos [HP96]. Debido a la ley de Amdahl el aumento
de velocidad en estos programas esta muy limitado. Dos razones por las que no se
obtiene un alto grado de vectorizacion son la presencia de condicionales (sentencias
if) dentro de los bucles y el uso de matrices dispersas. Los programas que contienen
sentencias if en los bucles no se pueden ejecutar en modo vectorial utilizando las tecnicas
expuestas en este captulo porque las sentencias condicionales introducen control de flujo
en el bucle. De igual forma, las matrices dispersas no se pueden tratar eficientemente
Ingeniera Informatica

Universidad de Valencia

24

Procesadores vectoriales
7

64

64

No encadenada

Total=141
MULTV

ADDV

64
MULTV

Encadenada

64
Total=77
ADDV

Figura 1.15: Temporizacion para la ejecucion no encadenada y encadenada.


utilizando algunas de las capacidades que se han mostrado; esto es por ejemplo un factor
importante en la falta de vectorizacion de Spice. Se explican a continuacion algunas
tecnicas para poder ejecutar de forma vectorial algunas de estas estructuras.
Dado el siguiente bucle:
do 100 i=1,64
if (A(i) .ne. 0) then
A(i)=A(i)-B(i)
endif
100 continue

Este bucle no puede vectorizarse a causa de la ejecucion condicional del cuerpo.


Sin embargo, si el bucle anterior se pudiera ejecutar en las iteraciones para las cuales
A(i) 6= 0 entonces se podra vectorizar la resta. Para solucionarlo se emplea una mascara
sobre el vector.
El control de mascara vectorial es un vector booleano de longitud MVL. Cuando se
carga el registro de mascara vectorial con el resultado de un test del vector, cualquier
instruccion vectorial que se vaya a ejecutar solamente opera sobre los elementos del
vector cuyas entradas correspondientes en el registro de mascara vectorial sean 1. Las
entradas del registro vectorial destino que corresponden a un 0 en el registro de mascara
no se modifican por la operacion del vector. Para que no act
ue, el registro de mascara
vectorial se inicializa todo a 1, haciendo que las instrucciones posteriores al vector
operen con todos los elementos del vector. Con esto podemos reescribir el codigo anterior
para que sea vectorizable:
LV
LV
LD
SNESV
SUBV
CVM
SV

V1,Ra
V2,Rb
F0,#0
F0,V1
V1,V1,V2
Ra,V1

;
;
;
;
;
;
;

Carga vector A en V1
Carga vector B en V2
Carga F0 con 0 en punto flotante
Inicializa VM a 1 si V1(i)!=0
Resta bajo el control de la m
ascara
Pone la m
ascara todo a unos
guarda el resultado en A.

El uso del vector de mascara tiene alguna desventaja. Primero, la operacion se


realiza para todos los elementos del vector, por lo que da lo mismo que la condicion se
cumpla o no, siempre consume tiempo de ejecucion. De todas formas, incluso con una
mascara repleta de ceros, el tiempo de ejecucion del codigo en forma vectorial suele ser
menor que la version escalar. Segundo, en algunos procesadores lo que hace la mascara
es deshabilitar el almacenamiento en el registro del resultado de la operacion, pero la
operacion se hace en cualquier caso. Esto tiene el problema de que si por ejemplo
Ingeniera Informatica

Universidad de Valencia

1.4 Mejora del rendimiento de los procesadores vectoriales

25

estamos dividiendo, y no queremos dividir por cero (para evitar la excepcion) lo normal
es comprobar los elementos que sean cero y no dividir, pero en un procesador cuya
mascara solo deshabilite el almacenamiento y no la operacion, realizara la division por
cero generando la excepcion que se pretenda evitar.

1.4.3

Matrices dispersas

Las matrices dispersas son matrices que tienen una gran cantidad de elementos, siendo
la mayora de ellos cero. Este tipo de matrices, que habitualmente ocuparan mucha
memoria de forma innecesaria, se encuentran almacenadas de forma compacta y son
accedidas indirectamente. Para una representacion tpica de una matriz dispersa nos
podemos encontrar con codigo como el siguiente:
100

do 100 i=1,n
A(K(i))=A(K(i))+C(M(i))

Este codigo realiza la suma de los vectores dispersos A y C, usando como ndices los
vectores K y M que designan los elementos de A y B que no son cero (ambas matrices
deben tener el mismo n
umero de elementos no nulos). Otra forma com
un de representar
las matrices dispersas utiliza un vector de bits como mascara para indicar que elementos
existen y otro vector para almacenar sus valores. A menudo ambas representaciones
coexisten en el mismo programa. Este tipo de matrices se encuentran en muchos codigos,
y hay muchas formas de tratar con ellas dependiendo de la estructura de datos utilizada
en el programa.
Un primer mecanismo consiste en las operaciones de dispersi
on y agrupamiento
utilizando vectores ndices. El objetivo es moverse de una representacion densa a la
dispersa normal y viceversa. La operacion de agrupamiento coge el vector ndice y
busca en memoria el vector cuyos elementos se encuentran en las direcciones dadas
por la suma de una direccion base y los desplazamientos dados por el vector ndice.
El resultado es un vector no disperso (denso) en un registro vectorial. Una vez se
han realizado las operaciones sobre este vector denso, se pueden almacenar de nuevo
en memoria de forma expandida mediante la operacion de dispersion que utilizara el
mismo vector de ndices. El soporte hardware para estas operaciones se denomina
dispersar-agrupar (scatter-gather). En el ensamblador vienen dos instrucciones para
realizar este tipo de tareas. En el caso del DLXV se tiene LVI (cargar vector indexado),
SVI (almacenar vector indexado), y CVI (crear vector ndice, por ejemplo CVI V1,R1
introduce en V1 los valores 0,R1,2*R1,3*R1,...,63*R1). Por ejemplo, suponer que Ra, Rc,
Rk y Rm contienen las direcciones de comienzo de los vectores de la secuencia anterior,
entonces el bucle interno de la secuencia se podra codificar como:
LV
LVI
LV
LVI
ADDV
SVI

Vk,Rk
Va,(Ra+Vk)
Vm,Rm
Vc,(Rc+Vm)
Va,Va,Vc
(Ra+Vk),Va

;
;
;
;
;
;

Carga K
Carga A(K(i))
Carga M
Carga C(M(i))
Los suma
Almacena A(K(i))

De esta manera queda vectorizada la parte de calculo con matrices dispersas. El


codigo en Fortran dado con anterioridad nunca se vectorizara de forma automatica
puesto que el compilador no sabra si existe dependencia de datos, ya que no sabe a
priori lo que contiene el vector K.
Ingeniera Informatica

Universidad de Valencia

26

Procesadores vectoriales

Algo parecido se puede realizar mediante el uso de la mascara que se vio en las
sentencias condicionales. El registro de mascara se usa en este caso para indicar los
elementos no nulos y as poder formar el vector denso a partir de un vector disperso.
La capacidad de dispersar/agrupar (scatter-gather ) esta incluida en muchos de los
supercomputadores recientes. Estas operaciones rara vez alcanzan la velocidad de un
elemento por ciclo, pero son mucho mas rapidas que la alternativa de utilizar un bucle
escalar. Si la propiedad de dispersion de un matriz cambia, es necesario calcular un
nuevo vector ndice. Muchos procesadores proporcionan soporte para un calculo rapido
de dicho vector. La instruccion CVI (Create Vector Index) del DLX crea un vector
ndice dado un valor de salto (m), cuyos valores son 0, m, 2 m, ..., 63 m. Algunos
procesadores proporcionan una instruccion para crear un vector ndice comprimido
cuyas entradas se corresponden con las posiciones a 1 en el registro mascara. En DLX,
definimos la instruccion CVI para que cree un vector ndice usando el vector mascara.
Cuando el vector mascara tiene todas sus entradas a uno, se crea un vector ndice
estandar.
Las cargas y almacenamientos indexados y la instruccion CVI proporcionan un
metodo alternativo para soportar la ejecucion condicional. A continuacion se muestra la secuencia de instrucciones que implementa el bucle que vimos al estudiar este
problema y que corresponde con el bucle mostrado en la pagina 24:
LV
LD
SNESV
CVI
POP
MOVI2S
CVM
LVI
LVI
SUBV
SVI

V1,Ra
F0,#0
F0,V1
V2,#8
R1,VM
VLR,R1
V3,(Ra+V2)
V4,(Rb+V2)
V3,V3,V4
(Ra+V2),V3

;
;
;
;
;
;
;
;
;
;
;

Carga vector A en V1
Carga F0 con cero en punto flotante
Pone VM(i) a 1 si V1(i)<>F0
Genera
ndices en V2
Calcula el n
umero de unos en VM
Carga registro de longitud vectorial
Pone a 1 los elementos de la m
ascara
Carga los elementos de A distintos de cero
Carga los elementos correspondientes de B
Hace la resta
Almacena A

El que la implementacion utilizando dispersar/agrupar (scatter-gather ) sea mejor


que la version utilizando la ejecucion condicional, depende de la frecuencia con la que
se cumpla la condicion y el coste de las operaciones. Ignorando el encadenamiento,
el tiempo de ejecucion para la primera version es 5n + c1 . El tiempo de ejecucion de
la segunda version, utilizando cargas y almacenamiento indexados con un tiempo de
ejecucion de un elemento por ciclo, es 4n + 4 f n + c2 , donde f es la fraccion de
elementos para la cual la condicion es cierta (es decir, A 6= 0. Si suponemos que los
valores c1 y c2 son comparables, y que son mucho mas peque
n os que n, entonces para
que la segunda tecnica sea mejor que la primera se tendra que cumplir
5n 4n + 4 f n
lo que ocurre cuando

1
4

f.

Es decir, el segundo metodo es mas rapido que el primero si menos de la cuarta


parte de los elementos son no nulos. En muchos casos la frecuencia de ejecucion es
mucho menor. Si el mismo vector de ndices puede ser usado varias veces, o si crece el
n
umero de sentencias vectoriales con la sentencia if, la ventaja de la aproximacion de
dispersar/agrupar aumentara claramente.
Ingeniera Informatica

Universidad de Valencia

1.5 El rendimiento de los procesadores vectoriales

1.5
1.5.1

27

El rendimiento de los procesadores vectoriales


Rendimiento relativo entre vectorial y escalar

A partir de la ley de Amdahl es relativamente sencillo calcular el rendimiento relativo


entre la ejecucion vectorial y la escalar, es decir, lo que se gana al ejecutar un programa
de forma vectorial frente a la escalar tradicional. Supongamos que r es la relacion de
velocidad entre escalar y vectorial, y que f es la relacion de vectorizacion. Con esto, se
puede definir el siguiente rendimiento relativo:
P =

1
r
=
(1 f ) + f /r
(1 f )r + f

(1.4)

Este rendimiento relativo mide el aumento de la velocidad de ejecucion del procesador


vectorial sobre el escalar. La relacion hardware de velocidad r es decision del dise
n ador.
El factor de vectorizacion f refleja el porcentaje de codigo en un programa de usuario
que se vectoriza. El rendimiento relativo es bastante sensible al valor de f . Este valor
se puede incrementar utilizando un buen compilador vectorial o a traves de transformaciones del programa.
Cuanto mas grande es r tanto mayor es este rendimiento relativo, pero si f es
peque
n o, no importa lo grande que sea r, ya que el rendimiento relativo estara cercano
a la unidad. Fabricantes como IBM tienen una r que ronda entre 3 y 5, ya que su
poltica es la de tener cierto balance entre las aplicaciones cientficas y las de negocios.
Sin embargo, empresas como Cray y algunas japonesas eligen valores mucho mas altos
para r, ya que la principal utilizacion de estas maquinas es el calculo cientfico. En
estos casos la r ronda entre los 10 y 25. La figura 1.16 muestra el rendimiento relativo
para una maquina vectorial en funcion de r y para varios valores de f .
5.5
90%
5

Rendimiento relativo (P)

4.5

4
80%

3.5

3
70%
2.5

2
50%
1.5
30%
1

4
5
6
7
relacion de velocidad escalar/vectorial (r)

10

Figura 1.16: Rendimiento relativo escalar/vectorial.

Ingeniera Informatica

Universidad de Valencia

28

Procesadores vectoriales

1.5.2

Medidas del rendimiento vectorial

Dado que la longitud del vector es tan importante en el establecimiento del rendimiento
de un procesador, veremos las medidas relacionadas con la longitud ademas del tiempo
de ejecucion y los MFLOPS obtenidos. Estas medidas relacionadas con la longitud
tienden a variar de forma muy importante dependiendo del procesador y que son importantes de comparar. (Recordar, sin embargo, que el tiempo es siempre la medida de
interes cuando se compara la velocidad relativa de dos procesadores.) Las tres medidas
mas importantes relacionadas con la longitud son
Rn . Es la velocidad de ejecucion, dada en MFLOPS, para un vector de longitud n.
R . Es la velocidad de ejecucion, dada en MFLOPS, para un vector de longitud infinita. Aunque esta medida puede ser de utilidad para medir el rendimiento maximo,
los problemas reales no manejan vectores ilimitados, y la sobrecarga existente en los
problemas reales puede ser mayor.
N1/2 . La longitud de vector necesaria para alcanzar la mitad de R . Esta es una
buena medida del impacto de la sobrecarga.
Nv . La longitud de vector a partir de la cual el modo vectorial es mas rapido que
el modo escalar. Esta medida tiene en cuenta la sobrecarga y la velocidad relativa
del modo escalar respecto al vectorial.
Veamos como se pueden determinar estas medidas en el problema DAXPY ejecutado
en el DLXV. Cuando existe el encadenamiento de instrucciones, el bucle interior del
codigo DAXPY en convoys es el que se muestra en la figura 1.17 (suponiendo que Rx
y Ry contienen la direccion de inicio).

LV V1,Rx

MULTSV V2,F0,V1

Convoy 1: chained load and multiply

LV V3,Ry

ADDV V4,V2,V3

Convoy 2: second load and ADD, chained

SV Ry,V4

Convoy 3: store the result

Figura 1.17: Formacion de convoys en el bucle interior del codigo DAXPY.


El tiempo de ejecucion de un bucle vectorial con n elementos, Tn , es:
l
Tn =

n m
(Tbucle + Tarranque ) + n Tcampanada
MV L

El encadenamiento permite que el bucle se ejecute en tres campanadas y no menos, dado que existe un cauce de memoria; as Tcampanada = 3. Si Tcampanada fuera
una indicacion completa del rendimiento, el bucle podra ejecutarse a una tasa de
2/3 tasa del reloj MFLOPS (ya que hay 2 FLOPs por iteracion). As, utilizando
u
nicamente Tcampanada , un DLXV a 200 MHz ejecutara este bucle a 133 MFLOPS suponiendo la no existencia de seccionamiento (strip-mining) y el coste de inicio. Existen
varias maneras de aumentar el rendimiento: a
n adir unidades de carga-almacenamiento
adicionales, permitir el solapamiento de convoys para reducir el impacto de los costes de
inicio, y decrementar el n
umero de cargas necesarias mediante la utilizacion de registros
vectoriales.
Ingeniera Informatica

Universidad de Valencia

1.5 El rendimiento de los procesadores vectoriales

29

Rendimiento m
aximo del DLXV en el DAXPY
En primer lugar debemos determinar el significado real del rendimiento maximo, R .
Por ahora, continuaremos suponiendo que un convoy no puede comenzar hasta que todas
las instrucciones del convoy anterior hayan finalizado; posteriormente eliminaremos esta
restriccion. Teniendo en cuenta esta restriccion, la sobrecarga de inicio para la secuencia
vectorial es simplemente la suma de los tiempos de inicio de las instrucciones:
Tarranque = 12 + 7 + 12 + 6 + 12 = 49
Usando M V L = 64, Tloop = 15, Tstart = 49, y Tchime = 3 en la ecuacion del
rendimiento, y suponiendo que n no es un m
ultiplo exacto de 64, el tiempo para una
operacion de n elementos es
lnm
Tn =
(15 + 49) + 3n = (n + 64) + 3n = 4n + 64
64
La velocidad sostenida esta por encima de 4 ciclos de reloj por iteracion, mas que la
velocidad teorica de 3 campanadas, que ignora los costes adicionales. La mayor parte
de esta diferencia es el coste de inicio para cada bloque de 64 elementos (49 ciclos frente
a 15 de la sobrecarga del bucle).
Podemos calcular R para una frecuencia de reloj de 200 MHz como

Operaciones por iteraci


on f recuencia de reloj
R = limn
Ciclos de reloj por iteraci
on
El numerador es independiente de n, por lo que
Operaciones por iteraci
on f recuencia de reloj
limn (Ciclos de reloj por iteraci
on)


Tn
4n + 64
= limn
=4
limn (Ciclos de reloj por iteraci
on) = limn
n
n
R =

R =

2 200 M Hz
= 100 M F LOP S
4

El rendimiento sin el coste de inicio, que es el rendimiento maximo dada la estructura


de la unidad funcional vectorial, es 1.33 veces superior. En realidad, la distancia entre
el rendimiento de pico y el sostenido puede ser incluso mayor.
Rendimiento sostenido del DLXV en el Benchmark Linpack
El benchmark Linpack es una eliminacion de Gauss sobre una matriz de 100 100. As,
la longitud de los elementos van desde 99 hasta 1. Un vector de longitud k se usa k
veces. As, la longitud media del vector viene dada por
P99 2
i
= 66.3
Pi=1
99
i=1 i
Ingeniera Informatica

Universidad de Valencia

30

Procesadores vectoriales

Ahora podemos determinar de forma mas precisa el rendimiento del DAXPY usando
una longitud de vector de 66.
Tn = 2 (15 + 49) + 3 66 = 128 + 198 = 326
R66 =

2 66 200 MHz
= 81 MFLOPS
326

El rendimiento maximo, ignorando los costes de inicio, es 1.64 veces superior que
el rendimiento sostenido que hemos calculado. En realidad, el benchmark Linpack
contiene una fraccion no trivial de codigo que no puede vectorizarse. Aunque este
codigo supone menos del 20% del tiempo antes de la vectorizacion, se ejecuta a menos
de una decima parte del rendimiento cuando se mide en FLOPs. As, la ley de Amdahl
nos dice que el rendimiento total sera significativamente menor que el rendimiento
estimado al analizar el bucle interno.
Dado que la longitud del vector tiene un impacto significativo en el rendimiento, las
medidas N1/2 y Nv se usan a menudo para comparar maquinas vectoriales.
Ejemplo Calcular N1/2 para el bucle interno de DAXPY para el DLXV con un reloj
de 200 MHz.
Respuesta Usando R como velocidad maxima, queremos saber para que longitud del
vector obtendremos 50 MFLOPS. Empezaremos con la formula para MFLOPS
suponiendo que las medidas se realizan para N1/2 elementos:
M F LOP S =

F LOP s ejecutados en N1/2 iteraciones Ciclos de reloj

106
Ciclos de reloj para N1/2 iteraciones
Segundos
50 =

2 N1/2
200
TN1/2

Simplificando esta expresion y suponiendo que N1/2 64, tenemos que Tn64 =
1 64 + 3 n, lo que da lugar a
TN1/2 = 8 N1/2
1 64 + 3 N1/2 = 8 N1/2
5 N1/2 = 64
N1/2 = 12.8
Por lo tanto, N1/2 = 13; es decir, un vector de longitud 13 proporciona aproximadamente la mitad del rendimiento maximo del DLXV en el bucle DAXPY.
Ejemplo Cual es la longitud del vector, Nv , para que la operacion vectorial se ejecute
mas rapidamente que la escalar?
Respuesta De nuevo, sabemos que Rv < 64. El tiempo de una iteracion en modo
escalar se puede estimar como 10 + 12 + 12 + 7 + 6 + 12 = 59 ciclos de reloj, donde
10 es el tiempo estimado de la sobrecarga del bucle. En el ejemplo anterior se vio
que Tn64 = 64 + 3 n ciclos de reloj. Por lo tanto,
64 + 3 Nv = 59 Nv

64
Nv =
56
Nv = 2
Ingeniera Informatica

Universidad de Valencia

1.5 El rendimiento de los procesadores vectoriales

31

Rendimiento del DAXPY en un DLXV mejorado


El rendimiento del DAXPY, como en muchos problemas vectoriales, viene limitado
por la memoria. Consecuentemente, este se puede mejorar a
n adiendo mas unidades de
acceso a memoria. Esta es la principal diferencia arquitectonica entre el CRAY X-MP (y
los procesadores posteriores) y el CRAY-1. El CRAY X-MP tiene tres cauces de acceso
a memoria, en comparacion con el u
nico cauce a memoria del CRAY-1, permitiendo
ademas un encadenamiento mas flexible. Como afectan estos factores al rendimiento?
Ejemplo Cual sera el valor de T66 para el bucle DAXPY en el DLXV si a
n adimos
dos cauces mas de acceso a memoria?.
Respuesta Con tres canales de acceso a memoria, todas las operaciones caben en un
u
nico convoy. Los tiempos de inicio son los mismos, por lo que

66
T66 =
(Tloop + Tarranque ) + 66 Tcampanada
64
T66 = 2 (15 + 49) + 66 1 = 194
Con tres cauces de acceso a memoria, hemos reducido el tiempo para el rendimiento sostenido de 326 a 194, un factor de 1.7. Observacion del efecto de la ley
de Amdahl: Hemos mejorado la velocidad maxima teorica, medida en el n
umero
de campanadas, en un factor de 3, pero la mejora total es de 1.7 en el rendimiento
sostenido.
Otra mejora se puede conseguir del solapamiento de diferentes convoys y del coste del
bucle escalar con las instrucciones vectoriales. Esta mejora requiere que una operacion
vectorial pueda usar una unidad funcional antes de que otra operacion haya finalizado,
complicando la logica de emision de instrucciones.
Para conseguir una maxima ocultacion de la sobrecarga del seccionamiento (stripmining), es necesario poder solapar diferentes instancias del bucle, permitiendo la ejecucion simultanea de dos instancias de un convoy y del codigo escalar. Esta tecnica,
denominada tailgating, se uso en el Cray-2. Alternativamente, podemos desenrollar el
bucle exterior para crear varias instancias de la secuencia vectorial utilizando diferentes
conjuntos de registros (suponiendo la existencia de suficientes registros). Permitiendo
el maximo solapamiento entre los convoys y la sobrecarga del bucle escalar, el tiempo
de inicio y de la ejecucion del bucle solo sera observable una u
nica vez en cada convoy.
De esta manera, un procesador con registros vectoriales puede conseguir unos costes de
arranque bajos para vectores cortos y un alto rendimiento maximo para vectores muy
grandes.
Ejemplo Cuales seran los valores de R y T66 para el bucle DAXPY en el DLXV
si a
n adimos dos cauces mas de acceso a memoria y permitimos que los costes del
seccionamiento (strip-mining) y de arranque se solapen totalmente?.
Respuesta

Operaciones por iteraci


on f recuencia de reloj
R = limn
Ciclos de reloj por iteraci
on

Tn
limn (Ciclos de reloj por iteraci
on) = limn
n
Ingeniera Informatica

Universidad de Valencia

32

Procesadores vectoriales
Dado que la sobrecarga solo se observa una vez, Tn = n + 49 + 15 = n + 64. As,

Tn
n + 64
limn
= limn
=1
n
n
2 200 MHz
= 400 MFLOPS
1
A
n adir unidades adicionales de acceso a memoria y una logica de emision mas
flexible da lugar a una mejora en el rendimiento maximo de un factor de 4. Sin
embargo, T66 = 130, por lo que para vectores cortos, la mejora en el rendimiento
= 2.5 veces.
sostenido es de 326
100
R =

1.6

Historia y evoluci
on de los procesadores vectoriales

Para finalizar, la figura 1.18 muestra una comparacion de la diferencia de rendimiento


entre los procesadores vectoriales y los procesadores superescalares de u
ltima generacion. En esta figura podemos comprobar como en los u
ltimos a
n os se ha ido reduciendo
la diferencia en rendimiento de ambas arquitecturas.

Ingeniera Informatica

Universidad de Valencia

1.6 Historia y evolucion de los procesadores vectoriales

33

10000

1000

T94
C90

DEC 8200
IBM Power2/990

Ymp
Xmp

MIPS R4400

100

Xmp

Linpack MFLOPS

HP9000/735
DEC Alpha AXP
HP 9000/750
IBM RS6000/540

Cray 1s

10
Cray n=1000
Cray n=100
Micro n=1000
Micro n=100

MIPS M/2000
MIPS M/120

1
1975

Sun 4/260

1980

1985

1990

1995

2000

Figura 1.18: Comparacion del rendimiento de los procesadores vectoriales y los microprocesadores escalares para la resolucion de un sistema de ecuaciones lineales denso
(tama
n o de la matriz=n n).

Ingeniera Informatica

Universidad de Valencia

34

Procesadores vectoriales

Ingeniera Informatica

Universidad de Valencia

También podría gustarte