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, afurfaro@electron.frba.utn.edu.ar 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.