Download Procesamiento Intensivo del ECG con procesadores IA-32 e IA-64

Document related concepts
no text concepts found
Transcript
XV CONGRESO ARGENTINO DE BIOINGENIERIA: COD-PAIS_NRO
1
Procesamiento Intensivo del ECG con
procesadores IA-32 e IA-64
Alejandro Furfaro, Mariano Llamedo Soria, Julián S. Bruno, Nahuel Gonzalez, Marcelo R. Risk
Facultad Regional Buenos Aires, Universidad Tecnológica Nacional,
[email protected]
Resumen— Los nuevos algoritmos de procesamiento de
registros prolongados de ECG buscan la minimización de la
intervención humana. Para lograr esto es necesario
implementar algoritmos muy complejos y eficientes, los cuales
requieren ser ejecutados en plataformas de alto rendimiento,
para de esta forma se puedan obtener los resultados en plazos
lo más breves posibles. El objetivo principal del presente
trabajo fue estimar el rendimiento de sistemas basados en
procesadores IA-32 e IA-64, en el procesamiento intensivo de
señales de ECG. Un total de diez registros Holter de
veinticuatro horas cada uno, fueron procesados, utilizando
filtros digitales y Transformada Rápida de Fourier; los
programas fuente fueron compilados, combinando dos tipos
de variables (double y float), utilizando compiladores gcc
(GNU C Complier de Linux) e icc (Intel C Compiler), con y
sin opción de optimización. Se emplearon en el presente
estudio, los procesadores Itanium 2, miembro de la
arquitectura IA-64, y Xeon, miembro de la arquitectura IA32, como exponentes de los modelos EPIC y superescalar
respectivamente. Mediante el procesamiento intensivo de
datos de ECG se determinaron las principales diferencias
entre ambas arquitecturas, y las ventajas de procesamiento al
utilizar el procesador Itanium 2, especialmente tratando datos
double. Además se verificó la mayor dependencia del
procesador Itanium 2 respecto de la eficiencia del compilador,
de acuerdo con los principios básicos del modelo EPIC en el
que se basa la arquitectura de este procesador.
Palabras clave— ECG, IA-64, IA-32, Xeon, Itanium, EPIC.
I. INTRODUCCIÓN
E
l procesamiento del electrocardiograma (ECG) es una
herramienta fundamental para el diagnóstico de las
enfermedades cardiovasculares. El ECG se puede
registrar en períodos cortos o largos, dependiendo de la
aplicación, es decir con registros cortos se estudian
generalmente respuestas evocadas a estímulos, y por otro
lado con registros largos se estudian respuestas
espontáneas. Los estudios Holter [1] utilizan registros
prolongados de 24 horas, generalmente de 2 o 3 canales. La
aplicación de los estudios va desde la determinación de
arritmias, la variabilidad de la frecuencia cardiaca [2], y el
estudio del desnivel del segmento ST para la determinación
de isquemias [3]. El desafío de los nuevos algoritmos de
procesamiento de registros prolongados de ECG es la
minimización de la intervención humana, tanto por los
errores que pueden incurrir los mismos como por el nivel
de experiencia necesaria. Para lograr esto es necesario
implementar algoritmos muy complejos y eficientes, los
cuales requieren ser ejecutados en plataformas de alto
rendimiento, para de esta forma se puedan obtener los
resultados en plazos lo más breves posibles [4].
Los procesadores modernos de alta gama han adoptado
arquitecturas tendientes a ejecutar instrucciones en forma
paralela, disponiendo diferentes Unidades de Ejecución,
basadas cada una en una subdivisión de las microoperaciones necesarias para ejecutar una instrucción del
procesador. Estas Unidades de Ejecución generalmente se
especializan en diferentes tipos de instrucción. El modelo
dominante durante los años 1990 ha sido el modelo
Superescalar, siendo la arquitectura IA-32 uno de los
modelos más difundidos.
Cada Unidad de ejecución, se compone de circuitos
lógicos o etapas capaces de ejecutar las diferentes fases o
micro operaciones básicas necesarias para completar una
instrucción: Búsqueda del código de operación (Fetch),
decodificación de la instrucción, control de las reglas de
protección, ejecución, y despacho del resultado (es decir, su
almacenamiento en el operando destino), por citar las mas
comunes.
La disposición de los diferentes circuitos lógicos que
ejecutan las micro-operaciones básicas de una instrucción
se denomina pipeline, y también trabajan en paralelo
ejecutando cada etapa una fase o micro operación de una
instrucción diferente, como se indica en la Figura 1.
1
2
3
4
5
6
7
Cloc k
Fa se d e
Búsq ueda
Busq. Busq. Busq. Busq. Busq. Busq. Busq.
Inst. 1 Inst. 2 Inst. 3 Inst. 4 Inst. 5 Inst. 6 Inst. 7
Fa se d e
Dec odifica ción
Dec. Dec. Dec. Dec. Dec. Dec.
Inst. 1 Inst. 2 Inst. 3 Inst. 4 Inst. 5 Inst. 6
Fase de Búsq ueda
d e Operand o
Busq. Busq. Busq. Busq. Busq.
Op. 1 Op. 2 Op. 3 Op. 4 Op. 5
Fa se d e
Ejec ución
Ejec. Ejec. Ejec. Ejec.
Inst. 1 Inst. 2 Inst. 3 Inst. 4
Fase d e Desp ac ho
de l resultad o
Escrib. Escrib. Escrib.
Res. 1 Res. 2 Res. 3
Fig. 1: Representación de fases de un pipeline
De este modo cada pipeline en régimen puede entregar
un resultado por ciclo de clock. Esta situación se representa
en la Figura 1 en la que podemos ver que a partir del 5to
pulso de clock se arriba a dicha situación de régimen.
En los modelos superescalares IA-32 se incluyen varios
pipelines diferentes cada uno de los cuales aplica esta
política. Por otra parte se diseñan de modo tal de repartir la
carga de trabajo de diferentes tipos de instrucciones
asegurando de este modo la posibilidad de ejecución
paralela de diferentes tipos de instrucciones, como por
ejemplo, transferencias hacia o desde memoria, saltos y
operaciones en punto flotante [5].
XV CONGRESO ARGENTINO DE BIOINGENIERIA: COD-PAIS_NRO
Este conjunto de pipelines permite al procesador entregar
varios resultados de instrucciones por ciclo de clock.
Sin embargo al realizar el hardware todo el esfuerzo para
resolver dependencias entre instrucciones paralelas y
conflictos de recursos, la arquitectura superescalar no logra
un rendimiento eficiente de los mismos.
El modelo EPIC (Explicitly Parallel Instruction
Computing), fue concebido por Hewlett-Packard para
superar estas limitaciones en el rendimiento en la ejecución
paralela de instrucciones. La arquitectura IA-64 basada en
el modelo EPIC, fue presentada por Intel en el procesador
Itanium.
Establece un cambio radical en el paradigma con que se
trabaja hasta su especificación: plantea realizar en tiempo
de compilación el análisis de dependencias que el modelo
superescalar realiza en el hardware. De este modo el
hardware no trata con el problema de las dependencias,
sino que son los compiladores quienes al armar el código
deben generar paquetes de instrucciones listas para
despachar en paralelo dentro de los pipelines del
procesador para su ejecución.
El hecho de trasladar complejidad en el diseño de los
compiladores permite a los diseñadores de hardware
concentrar su energía en proveer recursos abundantes de
ejecución, en lugar de preocuparse por implementar lógica
de control de dependencias y de resolución de conflictos en
los recursos de ejecución para manejar el despacho de
instrucciones a los pipelines.
El objetivo principal del presente trabajo fue estimar el
rendimiento de sistemas basados en procesadores IA-32 e
IA-64, en el procesamiento intensivo de señales de ECG.
II. MATERIAL Y MÉTODOS
Datos
Nuestro trabajo se basó en el procesamiento intensivo de
diez archivos, provenientes de diez estudios Holter de 24
horas cada uno; cada archivo contiene 2 canales de ECG
adquiridos a 256 muestras por segundo, lo cual totalizan
para cada archivo una longitud aproximada de 80 MBytes
[6].
Sistemas de procesamiento
En el presente trabajo se utilizaron los siguientes
sistemas: a) Sistema IA-32: un servidor con un procesador
Xeon de 2.8 GHz con tecnología Hyper Threading, de
arquitectura superescalar, 512 KB de memoria caché L2,
FSB 533 Mhz, 1 GB de RAM, Mother Intel SE7505VB2,
Chipset Intel E7505, y HD ATA 200GB, Sistema
Operativo Linux Fedora Core 3 kernel 2.6.9-5, y b) Sistema
IA-64: un servidor basado en procesador Itanium 2 de 1.5
GHz arquitectura EPIC, 400MHz. FSB, 6 Mbytes de
memoria cache L3, chipset Intel E8870, 8 Gbytes de RAM
DDR200, y controladora SCSI Ultra 320 con tres discos de
140 Gbytes en configuración RAID 5, Sistema Operativo
Linux Red Hat AS4 con Kernel 2.6.9-1.
Algoritmos
Se utilizó un algoritmo para la detección de la onda R y
la subsiguiente medición del intervalo RR y el cálculo del
espectro de frecuencias en registros ECG de superficie [7].
Este algoritmo realiza un filtrado mediante un filtro pasa
bajos (FIR Equiripple, Fc=50 Hz, 19 coeficientes) en
2
ambos canales. Luego se obtiene una señal resultante de la
siguiente fórmula:
x[n] = ch1[n] + ch2[n]
2
2
(1)
La finalidad de esta señal combinada es representar la
información de ambos canales simultáneamente. En caso
que algún canal sufra algún desperfecto (artefactos,
desconexión, etc.) esta señal conserva la información del
canal restante. En esta señal se procede a localizar la onda
R, y a determinar el intervalo RR. Luego se calculó el
espectro, utilizando la Transformada Rápida de Fourier
(TRF), de cada canal y el de la señal x[n]. Los resultados se
almacenan en un archivo separado por comas (formato csv)
para cada registro Holter.
Los algoritmos fueron implementados en dos versiones:
utilizando todas las variables en formato de punto flotante
simple precisión (float), y en formato de punto flotante de
doble precisión (double), en ambos casos de acuerdo a la
norma IEEE 754.
Todos los algoritmos fueron compilados con dos
herramientas: a) Compilador C GNU (gcc) Standard en las
distribuciones Linux, versión 3.4.2 para en el sistema IA-32
y versión 3.4.3 para el sistema IA-64, y b) Compilador C de
Intel (icc) versión 8.1, el cual fue diseñado específicamente
para los procesadores de Intel. Para ambos compiladores
existe la opción de optimización agresiva respecto al
procesador, la cual se invoca a través del modificador O3,
en la línea de comandos del compilador.
Los cálculos de la TRF se han efectuado utilizando GNU
Scientific Library (gsl) versión 1.6. Dicha librería se
compiló de manera consistente con el algoritmo en cada
caso, es decir, utilizando gcc o icc de acuerdo con la prueba
realizada.
Estimación del rendimiento
Para estimar el rendimiento de ambos sistemas se
tomaron time stamps con resolución de milisegundos en los
puntos de entrada y salida de los diferentes algoritmos. En
virtud de los volúmenes de información a procesar se
consideró suficiente la resolución adoptada.
Por otra parte a fin de evaluar el rendimiento puro de los
procesadores involucrados en la medición, se han
desarrollado procesos que acceden únicamente al disco y
bajan los archivos del ECG a memoria para computar el
tiempo de esta tarea también mediante la toma de time
stamps. Con los valores obtenidos se ajustaron los
resultados de los algoritmos de procesamiento de modo de
quitar la componente de acceso a disco en la medición.
Los resultados luego fueron analizados con una prueba
de Student para muestras apareadas, el nivel de
significancia estadística fue definido en 0.05.
III. RESULTADOS
La tabla I muestra los tiempos de procesamiento
obtenidos para cada combinación de procesador,
compilador, tipo de variable (double y float), y modificador
de optimización O3.
Las comparaciones entre los tiempos de procesamiento
del Itanium 2 vs el Xeon, fueron de una P < 0.001 en todos
los siguientes casos: a) para el compilador icc y double, b)
XV CONGRESO ARGENTINO DE BIOINGENIERIA: COD-PAIS_NRO
compilador icc y double O3, c) compilador icc y float, d)
compilador icc y float O3, e) compilador gcc y double, f)
compilador gcc y double O3, g) compilador gcc y float, y
h) compilador gcc y float O3.
TABLA I
TIEMPOS DE PROCESAMIENTO PARA CADA PROCESADOR Y COMPILADOR
EN SEGUNDOS (MEDIA ± DE).
Itanium2
con icc
Itanium 2
con gcc
Xeon con
icc
Xeon con
gcc
1,3,5,7
double
14.8±0.4 1
double O3
14.1±0.2
float
11±0.2 2
57.4±0.5 3
29±0.3
60.9±0.6 4
33.9±0.3
50.1±0.8
14.1±0.5
6
18.5±0.6
46.1±2
26.1±0.7 8
20.9±0.7
40.6±1.5
5
62.4±1.7 7
float O3
11.9±0.2
P<0.001 con double O3; 2,4,6,8 P<0.001 con float O3.
Tomado los resultados del procesador Itanium 2, los
programas compilados con gcc respecto de los compilados
con icc arrojaron las siguientes relaciones de rendimiento,
calculadas como el tiempo de procesamiento medio
compilado con gcc sobre el tiempo de procesamiento medio
compilado con icc, para los siguientes casos: a) 3.9 veces
para double, b) 2 veces para double O3, c) 5.5 veces para
float, y d) 2.8 veces para float O3. En el caso del
procesador Xeon, las mismas relaciones arrojaron los
siguientes valores: a) 1.5 veces para double, b) 0.9 veces
para double O3, c) 1.9 veces para float, y d) 1.1 veces para
float O3.
Las mismas relaciones de rendimiento para el Xeon
versus Itanium 2, compilados ambos con gcc arrojaron los
siguientes resultados: a) 1.1 para double, b) 1.6 para double
O3, c) 0.4 para float, y d) 0.6 para float O3. Las relaciones
de rendimiento para el Xeon versus Itanium 2, compilados
ambos con icc arrojaron los siguientes resultados: a) 2.7
para double, b) 3.5 para double O3, c) 1.3 para float, y d)
1.6 para float O3.
Las mismas relaciones de rendimiento para el Xeon
compilado con icc versus Itanium 2 compilado con gcc,
arrojaron los siguientes resultados: a) 0.7 para double, b)
1.7 para double O3, c) 0.2 para float, y d) 0.5 para float O3.
Las relaciones de rendimiento para el Xeon compilado con
gcc versus Itanium 2 compilado con icc, arrojaron los
siguientes resultados: a) 4.2 para double, b) 3.3 para double
O3, c) 2.4 para float, y d) 1.8 para float O3.
IV. DISCUSIÓN
El modelo de Arquitectura Superescalar tiene una
limitación que le impide aprovechar la totalidad de sus
recursos. Esta limitación se debe a varios factores que son
debidos al diseño mismo de las arquitecturas tanto RISC
como CISC.
Entre los más significativos podemos citar: 1)
Dependencia entre las instrucciones que ingresan a los
pipelines de ejecución: dos instrucciones contiguas en un
código compilado ingresarían juntas a sendos pipelines de
ejecución, pero si la segunda instrucción necesita como
operando al resultado de la anterior en la secuencia de
programa, las mismas no pueden ser ejecutadas en forma
3
paralela, ya que el resultado de la segunda instrucción será
erróneo por no haber tenido el valor correcto de uno de sus
operandos; 2) Demoras en el acceso a operandos o
instrucciones: esto ocurre cuando los datos a procesar no se
encuentran en la memoria cache del procesador, y se deben
traer desde la memoria RAM del sistema; esta situación
demanda un tiempo muy superior a los tiempos de
ejecución del procesador, poniendo en espera a toda la
secuencia de operaciones que dependen de este dato o del
resultado de la instrucción que queda demorada, y
ocasionan el bloqueo del pipeline que está ejecutando esa
instrucción; y 3) Conflicto de recursos: esta situación se
presenta cuando el compilador genera una secuencia de
instrucciones contiguas que requieren del mismo tipo de
pipeline de ejecución, y cuya cantidad es superior a de los
pipelines físicamente disponibles para ese tipo de
instrucciones.
En los modelos basados en arquitectura superescalar,
como los procesadores IA-32 todos estos aspectos son
verificados y luego, siempre que sea posible, son resueltos
dentro del hardware del procesador.
Por lo general todos los procesadores efectúan el control
de dependencias en una unidad de hardware previa a los
pipelines de ejecución, impidiendo así la ejecución paralela
de instrucciones que son interdependientes. Los
procesadores IA-32 han adoptado métodos muy
sofisticados como “ejecución fuera de orden” para permitir
la ejecución adelantada de instrucciones sin dependencias
poniendo en espera a otras instrucciones que si bien están
antes en la secuencia de código no pueden ejecutarse hasta
no contar con el resultado de otras instrucciones, o que
requieren un operando que no está en la memoria cache y
se debe transferir desde la memoria RAM del sistema [5].
El uso eficiente de los pipelines también se ve afectado
por las instrucciones de branch, tales como saltos
condicionales o incondicionales o llamadas a subrutina.
Estas instrucciones generan una discontinuidad en la
secuencia de código. Esto obliga a invalidar todas las
instrucciones subsiguientes al branch en la secuencia de
programa, ya que en realidad no se debieron haber
ejecutado.
Para salvar este inconveniente los procesadores IA-32
poseen unidades de predicción de salto, que permiten
inferir el resultado del branch. Este mecanismo de
inferencia se basa en la forma en que los compiladores
arman los lazos de instrucciones: siempre tratan de utilizar
saltos condicionales para retroceder al inicio del lazo. Esta
situación es aprovechada para predecir saltos. Pero cuando
la condición de lazo expira se tiene una falla en la
predicción que obliga a limpiar todo el pipeline generando
baches en el rendimiento del procesador[5].
Algunos procesadores han avanzado en ejecución
especulativa, es decir, ejecutar ambas ramas del branch
para luego descartar la que no corresponde a la condición
de salto que se produjo [5].
Por estos motivos la eficiencia de las arquitecturas
superescalares rara vez supera al 50%. Esto quiere decir
que en cada ciclo de clock, la mitad de los recursos del
procesador no pueden utilizarse.
A medida que la tecnología de integración avanza es
posible asignar más y más pipelines de ejecución. Pero las
limitaciones propias de la arquitectura superescalar
sumadas a la forma en que los compiladores generan el
XV CONGRESO ARGENTINO DE BIOINGENIERIA: COD-PAIS_NRO
código hacen que agregar indiscriminadamente pipelines no
mejore significativamente el rendimiento.
Algunos diseñadores han introducido mejoras en las
arquitecturas que permiten asignar los pipelines que quedan
sin utilizar a un segundo proceso o thread. Los
procesadores IA-32 denominan a esta innovación en su
arquitectura “Tecnología Hyper Threading”. El resultado de
aplicar este modelo permite llevar el rendimiento de los
procesadores por encima del 80%. Esta situación fue
evidente durante las mediciones del presente estudio
cuando no se hizo uso intensivo de las capacidades de
punto flotante de los procesadores involucrados, ya que el
procesador Xeon utilizado en las mediciones posee
Tecnología Hyper Threading.
La innovación introducida por el modelo EPIC se
traduce en la práctica en procesadores con gran cantidad de
pipelines de ejecución capaces de trabajar con máximo
rendimiento, pero muy fuertemente dependientes del
correcto diseño de los compiladores, los que ahora se
transforman en elementos fundamentales y críticos dentro
de la optimización de código.
Puesto en términos prácticos, el procesador Itanium 2
con el que hemos hecho nuestras pruebas, puede procesar
seis instrucciones por ciclo de clock, ya que los
compiladores resuelven los problemas de dependencias, y
no debe entonces colocar lógica para resolver por ejemplo
ejecución fuera de orden ni resolver dependencias.
Simplemente toma los paquetes de instrucciones que ha
preparado el compilador y los deriva a las unidades de
ejecución que correspondan.
Las seis instrucciones se envían al procesador en
paquetes de tres instrucciones ya pre-armados por el
compilador, con verificaciones de dependencias resueltas y
sin conflicto de recursos internos en el procesador. Una vez
dentro del Itanium 2 se distribuyen entre las unidades de
ejecución según los contenidos: cuatro Unidades
Aritmético Lógicas (ALU) para enteros de 64 bits de
precisión, cuatro unidades de ejecución para procesamiento
de instrucciones Multimedia basadas en el modelo de
ejecución conocido como Single Instruction Multiple Data
(SIMD) [5], [8], [9], tres unidades de ejecución de branch,
dos unidades de ejecución para carga y almacenamiento de
operandos, y cuatro unidades de ejecución de punto
flotante, dos de ellas de simple precisión y otras dos de
precisión extendida de acuerdo con el formato de la norma
IEEE 754 [10],[11],[12].
En el caso particular de las unidades de punto flotante, el
procesador Itanium 2 puede diferenciarse en aplicaciones
cálculo científico y aplicaciones en ingeniería, tal como
nuestros resultados lo muestran.
Para minimizar los tiempos de acceso a los datos los
procesadores IA-32 e IA-64 integran en el mismo chip
bancos de memoria RAM generalmente referidas como
memoria cache que les permiten almacenar dentro del chip
grandes cantidades de código y datos (operandos) de modo
de poder disponerlos con mínima demora ya que su acceso
dentro del procesador se efectúa a mayor velocidad
respecto de la memora RAM del sistema. El procesador
Itanium 2 incluye en el mismo chip tres niveles de memoria
cache, y el procesador Xeon, dos niveles. Existe una
diferencia de 12 veces en el tamaño del cache L3 del
Itanium 2 respecto del cache L2 del Xeon.
4
Resulta muy interesante comparar las diferencias de
ejecución para ambos sistemas al compilar los algoritmos
con gcc versus icc. El compilador gcc ha sido diseñado
para trabajar sobre diversas plataformas de hardware,
mientras que el icc ha sido desarrollado por Intel para
generar código de sus propios procesadores. Esta situación
a la luz de los resultados obtenidos en el presente estudio,
evidencia el costo en términos de tiempo de ejecución que
se paga para conseguir portabilidad a través del hardware.
La brecha entre los objetos generados con los citados
compiladores es claramente menor en el caso del Xeon
respecto del Itanium 2. Esto muestra claramente la
dependencia que el modelo EPIC, en el que se basa el
procesador Itanium2, tiene respecto del compilador.
V. CONCLUSIONES
Durante la ejecución de las pruebas hemos constatado
que la diferencia entre los rendimientos de un procesador
Itanium 2 y de un procesador Xeon, cuyas características
hemos descrito, consisten en una mayor dependencia
respecto de la eficiencia del compilador y un mejor
rendimiento para algoritmos de cálculo en los que
predomina el uso de variables de punto flotante para el
procesador Itanium 2.
AGRADECIMIENTOS
Los autores agradecemos a Pedro Arini por sus valiosas
sugerencias para la implementación de los algoritmos.
Los autores agradecemos a Intel Tecnología de
Argentina SA, por la donación del sistema Itanium 2,
otorgado dentro del subsidio para investigación por el
proyecto “Analysis of Heart Rate Variability, Arterial
Pressure and Pulse in Normotensive and Hypertensive
Subjects”.
REFERENCIAS
[1]
Holter NJ. New method for heart studies. Science. 1961 Oct
20;134:1214-20.
[2] Risk MR, Sobh JF, Barbieri R, Armentano RL, Ramirez AJ, and
Saul JP. Variabilidad de las senales cardio-respiratorias. 2.
Variabilidad a largo plazo. Rev Arg Bioing 2: 39–45, 1996.
[3] Stone PH. ST-segment analysis in ambulatory ECG (AECG or
Holter) monitoring in patients with coronary artery disease: clinical
significance and analytic techniques. Ann Noninvasive
Electrocardiol. 2005 Apr;10(2):263-78.
[4] Pardey J, Jouravleva S. The next generation holter revolution: from
analyze-edit-print to analyse-print. Computers in Cardiology 2004;
31:373-376.
[5] IA-32 Intel® Architecture Software Developer's Manual, Volume 1:
Basic Architecture. Intel Corp 2005.
[6] Sobh J, Risk MR, Barbieri R, Saul P. Database for ECG, arterial
blood pressure and respiration signal analisys: feature extraction,
spectral estimation, and parameter quantification. IEEE-EMBC and
CMBSC, vol 4, pp. 955-956, 1997.
[7] Risk M, Sobh J, Barbieri R, Saul P. A simple algorithm for QRS
peak location: use on long term ECG recordings from the HMSMIT-FFMS database. IEEE-EMBC 1995.
[8] Intel Itanium Architecture. Software Developer’s Manual Vol 1:
Applicaction Architectura. Release 2.1. Intel Corp 2002.
[9] Cerdeiro M, Furfaro A. Procesamiento Digital de Audio en tiempo
Real con Computadoras Personales. Reportes Técnicos del CPSI.
Año 1- Vol 1: 8:18, ISSN 1668-6314, 2005.
[10] McNairy C, Soltis D. Itanium 2 Processor Microarchitecture. IEEE
Micro, March-April, pp 44-55, 2003.
[11] Sharangpani H, Arora K. Itanium Processor Microarchitecture. IEEE
Micro, September-October: pp 24-43, 2000.
[12] Intel Itanium 2 Processor. Hardware Developer’s Manual. Intel Corp
2002.