sevilla, 15 de noviembre de 2011 patricio lópez gonzález...
TRANSCRIPT
2011
Aportación al diseño e implementación de los Turbo Decodificadores
Universidad de Sevilla
Escuela Superior de Ingenieros
Patricio López González
Tutor: Vicente Baena Lecuyer
Trabajo Fin de Máster
Máster en Electrónica, Tratamiento de Señal y
Comunicaciones
Sevilla, 15 de Noviembre de 2011
Patricio López Noviembre 2011
2
Patricio López Contenido Noviembre 2011
3
Contenido
ÍNDICE DE FIGURAS .................................................................................................................. 6
ÍNDICE DE TABLAS .................................................................................................................... 8
ABREVIATURAS ........................................................................................................................ 9
CAPÍTULO 1. INTRODUCCIÓN .............................................................................................. 11
INTRODUCCIÓN ............................................................................................................................. 12
1.1. Desarrollo de nuevos estándares de comunicaciones ............................................. 12 1.1.1. DVB................................................................................................................................... 12 1.1.2. LTE .................................................................................................................................... 12 1.1.3. WiMAX ............................................................................................................................. 12
1.2. Requisitos robustez y capacidad .............................................................................. 13 1.2.1. MIMO ............................................................................................................................... 13 1.2.2. FEC (Forward Error Correction) ........................................................................................ 13
1.3. Plataformas de simulación ...................................................................................... 14
1.4. Software Defined Radio ........................................................................................... 15
2. MOTIVACIÓN ....................................................................................................................... 15
3. OBJETIVO DEL PROYECTO ........................................................................................................ 15
4. APORTACIÓN ........................................................................................................................ 15
CAPÍTULO 2. CUDA PARA LA ACELERACIÓN DE SIMULACIONES EN MATLAB ....................... 17
1. INTRODUCCIÓN ..................................................................................................................... 18
2. APLICACIONES DE PROPÓSITO GENERAL EN PROCESADORES GRÁFICOS (GPGPU) ............................... 18
2.1. Por qué utilizar GPU’s? ............................................................................................ 18
2.2. Paralelismo de tareas vs paralelismo de datos ....................................................... 19
2.3. CPU vs GPU .............................................................................................................. 19
3. ARQUITECTURA NVIDIA ........................................................................................................ 20
4. CUDA (COMPUTE UNIFIED DEVICE ARCHITECTURE) .................................................................... 21
4.1. Interfaz de programación CUDA .............................................................................. 22 4.1.1. Estructura de un programa en CUDA ............................................................................... 22 4.1.2. Compilación...................................................................................................................... 24
4.1.2.1. Compilación con NVCC ............................................................................................. 24 4.1.2.2. Compilación desde el entorno matlab ..................................................................... 24
MEX Files .............................................................................................................................. 24 4.1.2.3. Compilación independiente ..................................................................................... 25
4.2. Consideraciones sobre la utilización de la memoria ................................................ 25 4.2.1. Optimización .................................................................................................................... 25
4.2.1.1. Transferencia entre el Host y la GPU ........................................................................ 26 4.2.1.2. Transferencias internas de la GPU............................................................................ 26
Acceso agrupado a memoria ................................................................................................ 27 Memoria Compartida ........................................................................................................... 28
Patricio López Contenido Noviembre 2011
4
Memoria Local ...................................................................................................................... 29 Memoria de textura (Texture memory) ............................................................................... 29 Memoria constante (Constant memory) .............................................................................. 29
Registros .................................................................................................................................... 29 4.2.2. Reserva de memoria ........................................................................................................ 30
4.3. Obtención de las máximas prestaciones ................................................................. 30
4.4. Consideraciones sobre la arquitectura Fermi de NVIDIA ......................................... 31 4.4.1. Comunicación de los threads dentro de un mismo warp ................................................. 32
5. CONCLUSIÓN ........................................................................................................................ 32
CAPÍTULO 3. TURBO CÓDIGOS ............................................................................................ 33
1. INTRODUCCIÓN ..................................................................................................................... 34
2. LOS TURBO CÓDIGOS ............................................................................................................. 35
2.1. Proceso de codificación ........................................................................................... 35
3. PROCESO DE DECODIFICACIÓN ................................................................................................. 36
3.1. Decodificadores SISO ............................................................................................... 37 3.1.1. SOVA ................................................................................................................................ 38 3.1.2. Algoritmo BCJR ................................................................................................................. 38
3.1.2.1. Algoritmo BCJR para códigos sistemáticos ............................................................... 41 Formulación LLR del algoritmo ............................................................................................. 42 Aproximación por el máximo. Max-Log-MAP ....................................................................... 43
4. TURBO CÓDIGOS M-ARIOS ...................................................................................................... 44
4.1. Ventajas de los Turbo Códigos m-arios.................................................................... 45
4.2. Algoritmo MAP para los Turbo Códigos m-arios ..................................................... 46
5. DOS CASOS CONCRETOS .......................................................................................................... 47
5.1. Turbo código de DVB-SH .......................................................................................... 47
5.2. Turbo código de DVB-RCS ........................................................................................ 48
5.3. Comparativa ............................................................................................................ 49
6. CONCLUSIÓN ........................................................................................................................ 49
CAPÍTULO 4. PARALELIZACIÓN DEL TURBO DECODER. ACS Y SLIDING WINDOW ................. 50
1. INTRODUCCIÓN ..................................................................................................................... 51
2. TÉCNICAS RADIX PARA LA PARALELIZACIÓN DE LOS DECODIFICADORES SISO. ..................................... 51
2.1. Cuello de botella algoritmo de Viterbi ..................................................................... 51 2.1.1. Rápida descripción del algoritmo de Viterbi .................................................................... 52 2.1.2. Posibles optimizaciones del algoritmo de Viterbi ............................................................ 53
2.2. De la técnica de anticipación a las estructuras Radix-N .......................................... 55
3. ALGORITMO DE VENTANA DESLIZANTE (SLIDING WINDOW) .......................................................... 55
3.1. Prestaciones de Sliding Window .............................................................................. 58
3.2. Paralelización con Sliding Window .......................................................................... 59
4. CONCLUSIÓN ........................................................................................................................ 62
CAPÍTULO 5. IMPLEMENTACIÓN DEL TURBO DECODER EN LA GPU ..................................... 63
1. INTRODUCCIÓN ..................................................................................................................... 64
2. TURBO DECODER M-ARIO ....................................................................................................... 64
3. PARALELIZACIÓN SIN PÉRDIDAS ................................................................................................ 66
3.1. Paralelización del cálculo de las branch metrics ...................................................... 66 3.1.1. Limitaciones GPU ............................................................................................................. 69
3.2. Cómputo de las A, B y LLR de salida en la GPU ........................................................ 69 3.2.1. Limitaciones GPU ............................................................................................................. 74
4. SLIDING WINDOW ................................................................................................................. 74
Patricio López Contenido Noviembre 2011
5
5. CONCLUSIÓN ........................................................................................................................ 76
CAPÍTULO 6. RESULTADOS DE LA IMPLEMENTACIÓN EN CUDA DEL TURBO DECODER ........ 77
1. INTRODUCCIÓN ..................................................................................................................... 78
2. RESULTADOS EXPERIMENTALES ................................................................................................ 78
3. RESULTADOS SIN PÉRDIDAS ..................................................................................................... 79
4. SLIDING WINDOW ................................................................................................................. 83
5. CONCLUSIÓN ........................................................................................................................ 84
CAPÍTULO 7. ANÁLISIS DE PRESTACIONES DEL TURBO DECODER EN PUNTO FIJO ............... 85
1. INTRODUCCIÓN ..................................................................................................................... 86
2. SIMPLIFICACIONES DEL ALGORITMO MAP .................................................................................. 86
3. MÉTRICAS PROVISTAS POR EL DEMAPPER ................................................................................... 86
4. IMPLEMENTACIÓN DEL TURBO DECODER EN PUNTO FIJO ............................................................... 88
4.1. Representación ........................................................................................................ 88
4.2. Cuantización de la función de corrección para el máximo ...................................... 89 4.2.1. Aproximación con Look Up Table ..................................................................................... 89 4.2.2. Aproximación Constant-Log-MAP .................................................................................... 93
4.3. Otras consideraciones ............................................................................................. 93 4.3.1. Bits parte fraccionaria ...................................................................................................... 93 4.3.2. Bucle de decodificación .................................................................................................... 94
5. RESULTADOS FINALES DE LA IMPLEMENTACIÓN EN PUNTO FIJO DEL TURBO DECODER .......................... 95
5.1. Diferencia prestaciones max/max* ......................................................................... 95
5.2. Resultados de pérdidas totales ................................................................................ 95
6. CONCLUSIÓN ........................................................................................................................ 97
CAPÍTULO 8. CONCLUSIÓN .................................................................................................. 98
RESULTADOS ................................................................................................................................ 99
TRABAJO FUTURO........................................................................................................................ 100
CAPÍTULO 9. REFERENCIAS ................................................................................................ 101
Patricio López Índice de figuras Noviembre 2011
6
Índice de figuras
FIGURA 1-1. PUNTOS CRÍTICOS EN LA SIMULACIÓN SOFTWARE DE UN SISTEMA INALÁMBRICO OFDM .............................. 14
FIGURA 2-1. DIFERENCIAS FUNDAMENTALES ENTRE CPU Y GPU .............................................................................. 19
FIGURA 2-2. ESQUEMA BÁSICO DE LA ARQUITECTURA CPU - GPU ........................................................................... 21
FIGURA 2-3. JERARQUÍA BÁSICA PARA LA PROGRAMACIÓN CUDA ............................................................................ 23
FIGURA 2-4. ETAPAS EN LA EJECUCIÓN DE UN PROGRAMA EN CUDA ........................................................................ 23
FIGURA 2-5. EJEMPLO DE COPIA Y EJECUCIÓN SOLAPADAS ....................................................................................... 26
FIGURA 2-6. ALINEACIÓN DE LA MEMORIA GLOBAL ................................................................................................ 28
FIGURA 2-7. ACCESO NO ALINEADO A MEMORIA GLOBAL ........................................................................................ 28
FIGURA 2-8. JERARQUIZACIÓN DE LA MEMORIA EN LA ARQUITECTURA FERMI .............................................................. 32
FIGURA 3-1. ESTRUCTURA BÁSICA DE UN TURBO CÓDIGO DE BLOQUES Y PARALELO...................................................... 36
FIGURA 3-2. ESQUEMA BÁSICO TURBO DECODER .................................................................................................. 37
FIGURA 3-3. MUESTRA DEL TRELLIS DEL PROCESO DE CODIFICACIÓN .......................................................................... 39
FIGURA 3-4. ESQUEMA DE UN TURBO CÓDIGO M-ARIO ......................................................................................... 45
FIGURA 3-5. TRELLIS CORRESPONDIENTE AL CRSC DEL TURBO CÓDIGO DE DVB-RCS .................................................. 46
FIGURA 3-6. ESQUEMA DEL TURBO CÓDIGO DE DVB-SH ....................................................................................... 47
FIGURA 3-7. ESQUEMA DEL CODIFICADOR RSC DEL TURBO CÓDIGO DE DVB-SH ........................................................ 48
FIGURA 3-8. ESQUEMA DEL TURBO CÓDIGO DE DVB-RCS ..................................................................................... 48
FIGURA 4-1. EJEMPLO DE TRELLIS BINARIO CON 4 ESTADOS ..................................................................................... 52
FIGURA 4-2. UNIDAD BÁSICA DE ADD COMPARE AND SELECT PARA UNA SELECCIÓN BINARIA.......................................... 53
FIGURA 4-3. TRELLIS COMPRIMIDO ..................................................................................................................... 54
FIGURA 4-4. BRANCH METRICS EQUIVALENTES ...................................................................................................... 54
FIGURA 4-5. PROCESO SECUENCIAL Y SIN SLIDING WINDOW ..................................................................................... 57
FIGURA 4-6. PROCESO DE DECODIFICACIÓN CON VENTANA DESLIZANTE (SLIDING WINDOW) .......................................... 57
FIGURA 4-7. REPRESENTACIÓN ALTERNATIVA DEL PROCESO DE VENTANA DESLIZANTE ................................................... 58
FIGURA 4-8. ALGORITMO DE VENTANA DESLIZANTE SIN PARALELIZACIÓN .................................................................... 60
FIGURA 4-9. ALGORITMO DE VENTANA DESLIZANTE CON PARALELIZACIÓN. ................................................................. 61
FIGURA 4-10. PERÍODO DE GUARDA TANTO PARA LAS A COMO LAS B EN LOS EXTREMOS DE CADA SUBBLOQUE .................. 62
FIGURA 5-1. ENCADENAMIENTO DE DOS TRELLIS BINARIOS. TRELLIS CORRESPONDIENTE A DVB-SH ................................ 65
FIGURA 5-2. TRELLIS DUO BINARIO, CORRESPONDIENTE A LA EXTENSIÓN DEL TRELLIS DE DVB-SH ................................... 65
FIGURA 5-3. ARQUITECTURA JERARQUIZADA Y DISTRIBUCIÓN DEL GRID PARA EL CÁLCULO DE LAS BRANCH METRICS. ........... 67
FIGURA 5-4. CÁLCULO DE LAS BRANCH METRICS EN LA GPU. EXTRACTO DE CÓDIGO ..................................................... 68
FIGURA 5-5. ESQUEMA DE EJECUCIÓN DE LA 1ª APROXIMACIÓN. BRANCH METRICS EN LA GPU ...................................... 69
FIGURA 5-6. ARQUITECTURA CUDA PARA EL CÁLCULO DE 8 MÁXIMOS SIMULTÁNEOS .................................................. 70
FIGURA 5-7. PARALELIZACIÓN DEL CÁLCULO DEL MÁXIMO ....................................................................................... 71
FIGURA 5-8. EXTRACTO DE CÓDIGO PARA EL CÁLCULO DEL MÁXIMO. SIN SINCRONIZACIÓN DENTRO DEL WARP .................. 72
FIGURA 5-9. ESQUEMA DE EJECUCIÓN DE LA 2ª APROXIMACIÓN. TODO EL DECODER EN LA GPU .................................... 73
FIGURA 5-10. DECODIFICACIÓN COMPLETA EN LA GPU. EXTRACTO DE CÓDIGO .......................................................... 73
FIGURA 5-11. ALGORITMO SLIDING WINDOW ...................................................................................................... 75
FIGURA 5-12. ESQUEMA DE LA ARQUITECTURA CON APLICACIÓN DEL ALGORITMO SLIDING WINDOW. ............................. 76
Patricio López Índice de figuras Noviembre 2011
7
FIGURA 6-1. CÁLCULO DE LAS BRANCH METRICS. RESTO DEL DECODER EN LA CPU ...................................................... 81
FIGURA 6-2. CÁLCULO DE LAS BRANCH METRICS. TODO EL DECODER EN LA GPU ........................................................ 81
FIGURA 6-3. COMPARACIÓN DE LAS IMPLEMENTACIONES SIN PÉRDIDAS ..................................................................... 82
FIGURA 6-4. CÓMPUTO DE LAS A Y B (SIN SLIDING WINDOW) ................................................................................ 82
FIGURA 7-1. ESQUEMA DEL TURBO DECODER PARA SU IMPLEMENTACIÓN EN PUNTO FIJO ............................................. 89
FIGURA 7-2. FUNCIÓN DE CORRECCIÓN. CUANTIZADO EJE X. SALIDAS EN FLOTANTE ..................................................... 90
FIGURA 7-3. APROXIMACIÓN DE LA FUNCIÓN DE CORRECCIÓN CON 4 BITS .................................................................. 91
FIGURA 7-4. APROXIMACIÓN DE LA FUNCIÓN DE CORRECCIÓN CON 3 BITS .................................................................. 91
FIGURA 7-5. FUNCIÓN DE CORRECCIÓN. 2 ENTRADAS ............................................................................................. 92
FIGURA 7-6. FUNCIÓN DE CORRECCIÓN 3 ENTRADAS. ............................................................................................. 93
Patricio López Índice de tablas Noviembre 2011
8
Índice de Tablas
TABLA 2-1. DIFERENTES TIPOS DE MEMORIA EN LA GPU Y SUS CARACTERÍSTICAS ......................................................... 27
TABLA 3-1. EXPRESIONES DE LAS MÉTRICAS PARA EL DECODER BINARIO Y M-ARIO ........................................................ 47
TABLA 3-2. COMPARATIVA DE PRESTACIONES DVB-RCS Y DVB-SH. TDM. CANAL AWGN ......................................... 49
TABLA 4-1. RELACIÓN DE PÉRDIDAS DEL ALGORITMO DE VENTANA DESLIZANTE EN FUNCIÓN DEL PERÍODO DE GUARDA PARA EL
ESTÁNDAR 3GPP FDD. ........................................................................................................................... 59
TABLA 4-2. INFLUENCIA DE LA SOBREITERACIÓN SOBRE EL ALGORITMO DE VENTANA DESLIZANTE .................................... 59
TABLA 5-1. COMPLEJIDAD DEL TURBO DECODER M-ARIO. ...................................................................................... 66
TABLA 6-1. RESUMEN DE LAS SIMULACIONES EN LOS BANCOS DE PRUEBA UTILIZADOS PARA LAS SIMULACIONES ................. 79
TABLA 6-2. RESULTADOS DE TIEMPO DE EJECUCIÓN PARA LA IMPLEMENTACIÓN SIN PÉRDIDAS ........................................ 80
TABLA 6-3. TIEMPOS DE EJECUCIÓN Y CARGA PARA EL CÁLCULO DE LAS BRANCH METRICS .............................................. 80
TABLA 6-4. TIEMPO DE EJECUCIÓN PARALELIZACIÓN SLIDING WINDOW ..................................................................... 83
TABLA 6-5. COMPARATIVA SILIDING WINDOW EN GPU VS CPU ............................................................................. 83
TABLA 6-6. ACELERACIÓN MÁXIMA OBTENIDA ...................................................................................................... 84
TABLA 7-1. PÉRDIDAS DEMAPPER PUNTO FIJO. LLR 10 BITS. QPSK .......................................................................... 87
TABLA 7-2. PÉRDIDAS DEMAPPER PUNTO FIJO. LLR 10 BITS. 16-QAM ..................................................................... 87
TABLA 7-3. PÉRDIDAS EXTRA LLR 5 BITS. QPSK .................................................................................................... 87
TABLA 7-4. PÉRDIDAS EXTRA LLR 5 BITS. 16-QAM ............................................................................................... 87
TABLA 7-5. NÚMERO DE BITS PARA LOS VALORES DE LA LUT. DEGRADACIÓN DE LA BER ............................................... 92
TABLA 7-6. ENTRADA EXTRA PARA EL MÁXIMO DE LA FUNCIÓN DE LA CORRECCIÓN. DEGRADACIÓN DE LA BER .................. 92
TABLA 7-7. PÉRDIDAS MAX Y MAX*. QPSK .......................................................................................................... 95
TABLA 7-8. PÉRDIDAS MAX Y MAX*. 16-QAM ..................................................................................................... 95
TABLA 7-9. RESULTADOS PÉRDIDAS TBDC EN PUNTO FIJO. CANAL AWGN ............................................................... 96
TABLA 7-10. RESULTADOS PÉRDIDAS TBDC EN PUNTO FIJO. CANAL COST207 .......................................................... 96
TABLA 7-11. PÉRDIDAS DE IMPLEMENTACIÓN HW ................................................................................................ 97
Patricio López Abreviaturas Noviembre 2011
9
Abreviaturas
ACS Add, Compare and Select
API Application Program Interface
AWGN Additive White Gaussian Noise
BCJR Bahl, Cock, Jelenik and Raviv
BER Bit Error Rate
BLAS Basic Linear Algebra Subprograms
BM Branch Metrics
BPSK Binary Phase Shift Keying
C/N Carrier to Noise Ratio
COTS Commercial Off the Shelf
CPU Central Processing Unit
CUDA Compute unified device architecture
DVB Digital Video Broadcasting
DVB-NGH Digital Video Broadcasting – Next Generation Handheld
DVB-RCS DVB – Return Channel satellite
DVB-SH DVB for Satellite Hanheld
DVB-T2 Digital Video Broadcasting – Second Generation Terrestrial
FDD Frequency-division duplexing
FEC Forward Error Correction
FER Frame Error Rate
FFT Fast Fourier Transform
FP Fixed Point
GPGPU General-Purpose computing on Graphics Processing Units
GPU Graphics Processing Units
LDPC Low Density Parity Check
LTE Long Term Evolution
LUT Look Up Table
Patricio López Abreviaturas Noviembre 2011
10
MAC Media Access Control
MAP Maximum A Posteriori
MEX Matlab Executable
MIMO Multiple Input Multiple Output
MPEG Moving Picture Experts Group
OFDMA Orthogonal Frecuency Division Multiple Access
PM Path Metrics
PTX Parallel thread execution
RSC Recursive Sistematic Convolutional
SIMD Single Instruction – Multiple Devices
SISO Soft Input Soft Output
SISO Soft Input, Soft Output
SM Streaming Multiprocessor
SOVA Soft Output Viterbi Algorithm
TBDC Turbo Decoder
TDD Time-Division Duplex
TDM Time Division Multiplex
VA Viterbi Algorithm
WiMAX Worldwide Interoperability for Microwave Access
Capítulo 1. Introducción
INTRODUCCIÓN ............................................................................................................................. 12
1.1. Desarrollo de nuevos estándares de comunicaciones ............................................. 12 1.1.1. DVB................................................................................................................................... 12 1.1.2. LTE .................................................................................................................................... 12 1.1.3. WiMAX ............................................................................................................................. 12
1.2. Requisitos robustez y capacidad .............................................................................. 13 1.2.1. MIMO ............................................................................................................................... 13 1.2.2. FEC (Forward Error Correction) ........................................................................................ 13
1.3. Plataformas de simulación ...................................................................................... 14
1.4. Software Defined Radio ........................................................................................... 15
2. MOTIVACIÓN ....................................................................................................................... 15
3. OBJETIVO DEL PROYECTO ........................................................................................................ 15
4. APORTACIÓN ........................................................................................................................ 15
Patricio López 1. Introducción Noviembre 2011
12
Introducción
En este punto pretendemos enmarcar el escenario en el que hemos realizado el
trabajo y los puntos que han motivado su realización
1.1. Desarrollo de nuevos estándares de comunicaciones
En los últimos años, los requisitos hacia los sistemas de comunicación inalámbricos se
han incrementado de forma drástica, siempre con el objetivo de llevar a cabo una utilización
más óptima del espectro y bajo el incremento constante de la demanda, sobre todo con la
aparición de nuevos servicios. Por ello, todos los organismos de estandarización se han puesto
manos a la obra para lanzar sistemas de una gran capacidad y con la posibilidad de integrarse
en otros sistemas para así satisfacer también las tendencias de convergencia en el mundo de
las redes de comunicaciones.
A continuación nombramos algunos de los organismos de estandarización más
importantes y de los que consta una importante apuesta por la evolución de los sistemas
inalámbricos. Damos algunas pinceladas sobre algunas características que nos han parecido
interesantes.
1.1.1. DVB
Actualmente uno de los proyectos más ambiciosos del grupo de DVB es la redacción de
un estándar para comunicaciones móviles, que abarque todas las buenas características de los
estándares DVB-T2 y DVB-SH. Se trata de DVB-NGH [1] , su objetivo es ir un paso más allá e
incrementar las prestaciones de los anteriores estándares orientados a comunicaciones
móviles e integrarse como una opción viable no sólo para la difusión de contenidos si no para
todo tipo de comunicaciones con una completa compatibilidad con otros estándares
existentes para comunicaciones móviles como pueden ser 3G o LTE.
1.1.2. LTE
LTE [2] es la marca corporativa que aúna a las tecnologías emergentes y ya
desarrolladas que comprenden las redes existentes 3G y 4G. La especificación LTE proporciona
picos de transmisión en el enlace de bajada (DL, Downlink) de al menos 100 Mbps (con una
transmisión MIMO 2x2), con picos de hasta casi 300 Mbps, con la utilización de esquemas
MIMO 4x4 y el de subida de unos 50 Mbps con latencias inferiores a los 10 ms en una
comunicación completa (petición y respuesta). LTE soporta anchos de banda escalables, desde
1,4 MHz hasta 20 Mhz y además soporta tanto la multiplexión por división en frecuencia (FDD,
Frequency Division Duplexing) como la multiplexión por división en el tiempo (TDD, Time
Division Duplexing).
1.1.3. WiMAX
El estándar WiMAX en su versión 802.16e [3] se ha establecido desde 2005 como una
opción plausible para satisfacer las necesidades de comunicación inalámbricas sobre todo en
áreas metropolitanas. Fundamentalmente actúa sobre los aspectos relacionados con el
interfaz aire, es decir sus capas más cercanas, la capa física y la capa MAC.
Patricio López 1. Introducción Noviembre 2011
13
802.16e utiliza la modulación OFDMA escalable para el transporte de la información y
soporta anchos de banda desde 1.25 MHz hasta 20 MHz, con símbolos de hasta 2048
subportadoras. Soporta una codificación y modulación adaptativa, de manera que en buenas
condiciones de recepción de señal se pueden usar esquemas eficientes como 64-QAM,
mientras que si la recepción de la señal es pobre se utilizarán esquemas mucho más robustos
como BPSK. Pero sobre todo queremos destacar la inclusión de esquemas de Multiple-Input
Multiple-Output que ya en 2005 se incluían en este estándar.
1.2. Requisitos robustez y capacidad
Presentamos dos puntos clave en la evolución de los sistemas de comunicación
inalámbricos, que han hecho posible dar un salto importante en las prestaciones de los
sistemas pero que también acarrean un importante aumento de la complejidad del sistema.
1.2.1. MIMO
Durante una década, las universidades y los laboratorios de investigación dedicados a
los sistemas de comunicaciones inalámbricos han propuesto la combinación de la transmisión
con múltiples antenas [4] con algoritmos avanzados de procesamiento de señal para crear
sistemas a veces llamados de smart-antenna, pero también conocidos sistemas multiple-input
multiple-output (MIMO). Estos esquemas están empezando a hacerse visibles en los
principales sistemas de comunicación. De hecho, las tecnologías MIMO ya se pueden
encontrar en puntos de acceso de redes de área local inalámbricas (por ejemplo en los
sistemas basados en 802.11n). Esto ha llevado a las tecnologías MIMO a ser contempladas por
los estándares WiMAX, 3GPP y DVB.
Actualmente existen diversos esquemas MIMO estandarizados en los sistemas 3GPP y
la estación base tiene la capacidad de seleccionar el esquema MIMO que mejor se adapte a las
condiciones de canal en cada momento.
La tecnología MIMO ocupa un espacio importante en la elaboración de los nuevos
estándares ya que un correcto diseño permite superar la barrera establecida por Shannon y
diseñar códigos con tasas de transmisión mayores que 1. Este avance viene acompañado por
supuesto de un importante incremento de la complejidad y que con las técnicas actuales se
hace factible, no sin dificultades, su implementación en dispositivos móviles.
1.2.2. FEC (Forward Error Correction)
Otro de los puntos clave dentro de la evolución de los sistemas de comunicación
inalámbricos son los algoritmos de decodificación de errores, los cuales proporcionan al
receptor la capacidad de corregir una determinada cantidad de errores de forma autónoma.
Los algoritmos que más peso han tomado son sobre todo los LDPC [5] (Low Density
Parity Check) y los Turbo Códigos [6] . En general son algoritmos maduros concebidos hace
bastantes años pero de inviable implementación hasta a actualidad debido a su complejidad.
Patricio López 1. Introducción Noviembre 2011
14
1.3. Plataformas de simulación
En el proceso de desarrollo de nuevos estándares, es fundamental la realización de
simulaciones [7] a distintos niveles, ya que permiten la evaluación de diversos algoritmos sin la
necesidad de ninguna implementación hardware, o al menos ayuda a elegir los mejores
candidatos para su posterior análisis en prototipos.
Los algoritmos FEC y MIMO anteriormente mencionados como factores clave en la
evolución de estos sistemas no sólo son complejos en su implementación hardware, esto se
traslada de igual manera a la simulación y en concreto al tiempo de simulación. Se han
desarrollado códigos MIMO que combinan diversas portadoras y esto deriva en espacios de
señal amplísimos cuya demodulación es extremadamente compleja. En el plano de la
simulación, la prueba de estos sistemas puede llevar semanas, en un proceso de
estandarización cuya duración puede ser de meses, este tiempo no es para nada despreciable.
De la misma manera, su propia naturaleza iterativa hace que los algoritmos de
decodificación de los LDPC y los Turbo Códigos sean especialmente pesados y ocupen una
fracción importante de las simulaciones.
En la Figura 1-1 hemos representado un esquema de típico de un simulador en banda
base para un sistema basado en OFDM. Hemos señalado sus puntos críticos en tiempo de
simulación. Este modelo básico actualmente ha evolucionado donde incluso los bloques de
detección y FEC se realimentan en un esquema Turbo-MIMO, lo que acentúa incluso más la
necesidad de optimizar los tiempo de ejecución de dichos bloques.
Can
al MIM
O + R
uid
o A
WG
N
Generación de flujo aleatorio
de datos
Codificación de canal
Entrelazado de canal
Codificador STBC
ModulaciónOFDM
(IFFT+GI)
Demodulación OFDM
(FFT – GI)
Sincronización Estimación de canal
Detección MIMO
Decodificador STBC
DesentrelazadoDecodificador
FECRecogida de
datos
BER
Figura 1-1. Puntos críticos en la simulación software de un sistema inalámbrico OFDM
Patricio López 1. Introducción Noviembre 2011
15
1.4. Software Defined Radio
Aunque no hemos de olvidar que la ejecución software de estos algoritmos sobrepasa
las fronteras de la simple simulación si hablamos de Sofware Defined Radio, donde éstos
deben cumplir las especificaciones de throughput y ejecutarse en tiempo real.
2. Motivación
El Turbo Decoder como cuello de botella en los tiempos de simulación de los modelos
de sistemas de comunicaciones y los nuevos retos relacionados con Software Defined Radio
han motivado la realización de este trabajo. Aunque fundamentalmente las necesidades de
búsqueda de soluciones han surgido desde la participación en proyectos de gran envergadura
a nivel nacional e internacional partiendo de la participación activa del grupo de investigación
en el organismo de estandarización europeo para la televisión digital (DVB).
Como hilo conductor para este trabajo hemos de señalar como fundamental la
participación del grupo en el proyecto TID-DVB-SIDSA, donde se han realizado grandes
esfuerzos para la implementación de un receptor de DVB-SH. Esta colaboración ha originado
resultados incluidos en este trabajo y de la misma manera ha servido de motivación para el
estudio de la aceleración de la plataforma de simulación. Al mismo tiempo, la participación del
grupo dentro del proyecto Furia (Futura Red Integrada Audiovisual) nos ha alentado a buscar
nuevas líneas de investigación, muchas de ellas fruto del intercambio de conocimiento surgido
de este proyecto
3. Objetivo del proyecto
1. Realizar una implementación paralela del Turbo Decoder para el estándar DVB-SH
utilizando la herramienta CUDA proporcionada por NVIDIA que permite su
ejecución sobre dispositivos de procesamiento paralelo en masa como son las
tarjetas gráficas.
2. Estudio de la implementación en punto fijo del Turbo Decoder para DVB-SH.
Análisis de prestaciones.
4. Aportación
Fundamentalmente, la aportación de este trabajo se puede resumir en los siguientes
puntos:
1. Desarrollo de un Turbo Decoder paralelo ejecutable sobre la tarjeta gráfica y que
consigue aceleraciones sobre el anterior de hasta 20 veces.
2. Análisis de las prestaciones de este tipo de implementación paralela sobre los
Turbo Códigos M-arios tomando como base el Turbo Código de DVB-SH
3. Análisis de prestaciones y procedimiento de cuantización para el Turbo Decoder de
DVB-SH y su posterior implementación hardware.
4. Fruto del trabajo conjunto con SIDSA, la plataforma de simulación dedicada a DVB-
SH ha permitido la implementación de un receptor en banda S [37] de muy altas
Patricio López 1. Introducción Noviembre 2011
16
prestaciones. En [37] encontramos el Final Report enviado a la ESA, contratante
del proyecto.
Estas aportaciones en torno a la plataforma de simulación de DVB-SH han permitido el
estudio de distintos algoritmos y prestaciones, dando lugar a las siguientes publicaciones:
Cinta Oria, Vicente Baena, Joaquín Granado, José García, Darío Pérez-Calderón,
Patricio López, David Ortiz. Performance evaluation of complementary code
combining diversity in DVB-SH. Digital Signal Processing, Volume 21, Issue 6,
December 2011, Pages 718-724.
Cinta Oria, Patricio López, José García, Darío Pérez-Calderón, Vicente Baena, David
Ortiz. Reduced Complexity ICI Cancellation Scheme for OFDM DVB-SH Receivers.
Proceedings of the XXV Conference on design of circuits and integrated Systems.
Pp 43-47. 2010
M-binary Turbo Decoder Acceleration using CUDA. Patricio López; Vicente Baena
Lecuyer; Ana Cinta Oria Oria; Jose García Doblado and Darío Pérez-Calderón
Rodríguez. XXVI Conference on Design of Circuits and Integrated Systems. 2011.
Capítulo 2. CUDA para la aceleración de simulaciones en MATLAB
1. INTRODUCCIÓN ..................................................................................................................... 18
2. APLICACIONES DE PROPÓSITO GENERAL EN PROCESADORES GRÁFICOS (GPGPU) ............................... 18
2.1. Por qué utilizar GPU’s? ............................................................................................ 18
2.2. Paralelismo de tareas vs paralelismo de datos ....................................................... 19
2.3. CPU vs GPU .............................................................................................................. 19
3. ARQUITECTURA NVIDIA ........................................................................................................ 20
4. CUDA (COMPUTE UNIFIED DEVICE ARCHITECTURE) .................................................................... 21
4.1. Interfaz de programación CUDA .............................................................................. 22 4.1.1. Estructura de un programa en CUDA ............................................................................... 22 4.1.2. Compilación...................................................................................................................... 24
4.1.2.1. Compilación con NVCC ............................................................................................. 24 4.1.2.2. Compilación desde el entorno matlab ..................................................................... 24
MEX Files .............................................................................................................................. 24 4.1.2.3. Compilación independiente ..................................................................................... 25
4.2. Consideraciones sobre la utilización de la memoria ................................................ 25 4.2.1. Optimización .................................................................................................................... 25
4.2.1.1. Transferencia entre el Host y la GPU ........................................................................ 26 4.2.1.2. Transferencias internas de la GPU............................................................................ 26
Acceso agrupado a memoria ................................................................................................ 27 Memoria Compartida ........................................................................................................... 28 Memoria Local ...................................................................................................................... 29 Memoria de textura (Texture memory) ............................................................................... 29 Memoria constante (Constant memory) .............................................................................. 29
Registros .................................................................................................................................... 29 4.2.2. Reserva de memoria ........................................................................................................ 30
4.3. Obtención de las máximas prestaciones ................................................................. 30
4.4. Consideraciones sobre la arquitectura Fermi de NVIDIA ......................................... 31 4.4.1. Comunicación de los threads dentro de un mismo warp ................................................. 32
5. CONCLUSIÓN ........................................................................................................................ 32
Patricio López Capitulo 2. CUDA para la aceleración de
simulaciones en Matlab
Noviembre 2011
18
1. Introducción
En este capítulo describiremos la herramienta que utilizaremos para plasmar las
arquitecturas paralelizadas de los componentes en cuestión de nuestro receptor y así traducir
esa nueva arquitectura en una aceleración software, aprovechable tanto en simulaciones
como en posibles aplicaciones de Software Radio.
Primeramente justificaremos la utilización de los procesadores gráficos para llevar a
cabo esta tarea, y describiremos la herramienta proporcionada por la fabricante NVIDIA para
el aprovechamiento de los recursos de sus tarjetas gráficas con fines de propósito general, ya
que en nuestro caso, utilizaremos los recursos para implementar un algoritmo de turbo
decodificación.
A su vez describiremos los aspectos que hay que tener en cuenta para la programación
de este algoritmo, pues es preciso tener unas pequeñas nociones del hardware para así
conseguir unas buenas prestaciones en el resultado final. Así mencionaremos aspectos de
compilación, acceso a memoria, estructuración del algoritmo, etc.
2. Aplicaciones de propósito general en procesadores gráficos
(GPGPU)
Se conoce como GPGPU [8] (General-Purpose computing on Graphics Processing Units)
a la técnica de utilizar la GPU (Graphics Processing Unit), que normalmente realiza cálculos
relacionados con el tratamiento y la representación de gráficos, para llevar a cabo aplicaciones
que tradicionalmente hacía la CPU. Esto se ha conseguido gracias a la inclusión de etapas
programables y aritmética de mayor precisión en las secuencias de renderizado, lo que
permite a los desarrolladores de software utilizar el stream processing (procesos del tipo SIMD,
Single Instruction – Multiple Device) sobre datos no relacionados con los gráficos.
Esta nueva técnica abre multitud de posibilidades y su abanico de utilización es muy
amplio. Podemos cubrir aplicaciones para la realización de operaciones con vectores y
matrices de grandes dimensiones (BLAS, Basic Linear Algebra Subprograms), simulación de
dinámicas moleculares, procesamiento digital de señales (como la realización de FFT), ray
tracing (técnica también utilizada en el cálculo de coberturas), simulación de físicas (colisiones,
fluidos,…), reconocimiento de voz, tratamiento de bases de datos, algoritmos de búsqueda y
ordenación, procesamiento de imágenes médicas, y un largo etcétera.
2.1. Por qué utilizar GPU’s?
Pero nos preguntaremos cuál es la razón básica por la que se utilizan las GPU. Se ha
establecido un modelo comercial para el hardware basado en componentes (COTS,
Commercial Off the Shelf) preparados para su utilización inmediata sin la necesidad de aplicar
ninguna modificación o mantenimiento. Esto ha hecho que se pueda disponer fácilmente de
una GPU en cada máquina de trabajo. A su, vez la velocidad de cálculo en determinadas
operaciones supera con creces a la ofrecida por la CPU.
Patricio López Capitulo 2. CUDA para la aceleración de
simulaciones en Matlab
Noviembre 2011
19
2.2. Paralelismo de tareas vs paralelismo de datos
El diseño orientado al paralelismo de tareas (task parallelism) se basa en la concepción
de procesos independientes y su sincronización con relativamente escasa comunicación. Este
tipo de paralelismo lo llevan a cabo normalmente los sistemas operativos para la distribución
de recursos en un sistema multiprocesador, y los hilos (threads) pueden ejecutar el mismo o
diferente código.
El paralelismo de datos (data parallelism) se basa en la existencia de grandes
cantidades de datos que precisan exactamente el mismo procesamiento. En un sistema
multiprocesador que ejecuta un único conjunto de instrucciones (SIMD, Single Instruction
Multiple Devices), el paralelismo de datos se consigue cuando cada procesador lleva a cabo la
misma tarea sobre diferentes sectores de los datos distribuidos. A veces, un único thread
controla las operaciones sobre los “trozos” de datos, en otras ocasiones, varios threads se
ocupan del control, pero éstos siguen ejecutando el mismo código. Es importante que no
existan dependencias entre los cálculos realizados por diferentes hilos y frecuentemente
requiere el rediseño de los algoritmos tradicionales para su adaptación a este tipo de
procesamiento.
2.3. CPU vs GPU
Fundamentalmente, la CPU destaca porque tiene una muy buena jerarquización de la
memoria y se puede contar con una reutilización muy ágil de los datos (memoria caché).
Ofrece una gran capacidad de ramificación de la ejecución de cada hilo (Fine branching
granurality) y pueden ejecutarse multitud de procesos distintos simultáneamente. No hay que
olvidar, que ofrece las prestaciones óptimas para la ejecución de un único thread.
Como podemos ver reflejado en la Figura 2-1, La GPU se caracteriza por estar formada
por multitud de unidades de cálculo matemático. También ofrece un acceso muy rápido a la
memoria integrada y una tasa de cálculo enorme en el procesamiento paralelo.
DRAM
CONTROL
ALU
ALU
ALU
ALU
Cache
CPU
DRAM
GPU
Figura 2-1. Diferencias fundamentales entre CPU y GPU
Por lo que se puede concluir que las CPU son apropiadas para el paralelismo de tareas
(task parallelism), mientras que las GPU funcionan de forma óptima con el paralelismo de
datos (data parallelism).
Patricio López Capitulo 2. CUDA para la aceleración de
simulaciones en Matlab
Noviembre 2011
20
Las GPU están diseñadas para tareas paralelas como viene a ser el renderizado y
procesa independientemente vértices y fragmentos (vertex and fragments) sin ninguna
comunicación entre dichos procesos. El sistema de memoria de las GPU está preparado para
encauzar el elevado flujo de datos en paralelo, por lo que se suelen prefijar accesos lineales a
los datos y siempre se persigue enmascarar la latencia de las transferencias de memoria.
Es importante que nos familiaricemos con el vocabulario específico utilizado en este
campo. Cabe destacar los streams, que no son más que el conjunto de registros que requieren
un mismo procesamiento. Y por supuesto los kernels, que son las funciones aplicadas a cada
elemento del stream.
3. Arquitectura NVIDIA
Será esencial que tengamos en la mente una imagen de la arquitectura general para la
que programamos, esto nos ayudará a comprender mejor algunas apreciaciones sobre la
forma de implementar los algoritmos paralelizados que son objeto de este proyecto. Podemos
observar la arquitectura típica de una GPU en la Figura 2-2 podemos ver un esquema de las
partes fundamentales de un procesador gráfico y de su interfaz con la CPU. Principalmente
hemos de destacar el diseño jerarquizado de los distintos niveles de memoria, así como su
ubicación (on/off chip) ya que serán aspectos clave a la hora de conseguir una tasa alta en
nuestros cálculos, pues la latencia de acceso a memoria es un factor limitante en la aceleración
que podamos conseguir.
La última generación de procesadores multi stream (Streaming multiprocessor)
desarrollada por NVIDIA [9] introduce diversas innovaciones en la arquitectura clásica.
Actualmente se ha mejorado esta arquitectura para mejorar en la precisión de gráficos
complejos así como en la computación de grandes cargas.
Apoyándonos en dicha figura, donde se representan los cores (unidades básicas de
cálculo) y extendiendo este esquema a la nueva arquitectura, hemos de apuntar que la actual
tecnología NVIDIA consta de 32 procesadores CUDA por cada streaming multiprocessor (SM),
es decir se ha multiplicado por 4 la estructura de anteriores diseños. Esta nueva arquitectura,
junto con una escalabilidad añadida permite alcanzar las máximas prestaciones en una gran
variedad de cómputos de texturas, mapas de sombras, etc.
En las nuevas GPU cada procesador CUDA contiene su propia canalización para las
operaciones aritmético lógicas con enteros (ALU), así como una unidad de punto flotante
(FPU). Esta generación de multiprocesadores también mejora la eficiencia en ejecución ya que
cada SM es capaz de controlar grupos de 32 threads (como veremos más adelante, llamados
warps). Cada SM contiene dos controladores para sendos grupos de 32 threads y dos unidades
para la atención de instrucciones por lo que se podrán ejecutar concurrentemente dos warps.
Al existir una ejecución totalmente independiente al nivel de warp, el scheduler de la GPU no
tendrá que realizar ninguna comprobación de dependencias dentro del flujo de instrucciones.
Patricio López Capitulo 2. CUDA para la aceleración de
simulaciones en Matlab
Noviembre 2011
21
Me
mo
ria
co
mp
art
ida
Re
gis
tro
s
Cor
e 1
Cor
e 2
Cor
e 3
Cor
e 4
Cor
e 5
Cor
e 6
Cor
e 7
Cor
e 8
Lo
ca
l
Te
xtu
ra
Co
nsta
nt.
Funciones
especiales
Str
ea
m M
ultip
roce
sso
r x N
Se
cció
n “
On
ch
ip”
Red de interconexión
Unidad de precisión
doble
GPU
Memoria global
Memoria del Host
Cache
Cor
e 1
Cor
e 2
Cor
e 3
Cor
e 4
PCI
Express
Ca
ch
é d
e te
xtu
raC
ach
e d
e m
em
oria
co
nsta
nte
CPU
Figura 2-2. Esquema básico de la arquitectura CPU - GPU
4. CUDA (Compute Unified Device Architecture)
Un sistema de computación consiste de un host, que es la tradicionalmente llamada
CPU (Central Processing Unit) y uno o más dispositivos (devices) formados por una gran
cantidad de procesadores en paralelo equipados con un número de unidades aritméticas. En
las aplicaciones modernas, existen normalmente secciones que presentan una rica cantidad de
paralelismo de datos, propiedad que permite estructurar la ejecución para que se realice de
forma simultánea.
Muchas de las aplicaciones software que procesan grandes cantidades de datos y que
por lo tanto derivan en tiempos de ejecución enormes, han sido diseñadas para modelar
fenómenos físicos del mundo real. Las imágenes y los fotogramas de los vídeos son muestras
del entorno donde se capturan distintos fenómenos físicos, eventos normalmente
independientes. La física del estado sólido y la dinámica de fluidos modelan fuerzas naturales y
movimientos que se pueden evaluar de forma independiente en pequeños pasos de tiempo.
Así como en nuestro caso, diferentes procesos independientes que conforman el proceso de
comunicación inalámbrico de los últimos sistemas de telecomunicaciones. Esta posibilidad de
Patricio López Capitulo 2. CUDA para la aceleración de
simulaciones en Matlab
Noviembre 2011
22
evaluar los problemas de forma independiente es la base del paralelismo para dichas
aplicaciones.
CUDA, de las siglas de Compute Unified Device Architecture es una arquitectura de
computación paralela desarrollada por NVIDIA. Se trata del motor de computación de NVIDIA
para las unidades de procesamiento gráfico (GPU) y que es accesible para los desarrolladores
de software a través de distintos lenguajes de programación estándar.
Esta herramienta proporciona a los desarrolladores acceso a un conjunto de
instrucciones virtuales y a la memoria de los elementos de computación paralela presentes en
las GPU. Con la utilización de CUDA, las últimas tarjetas gráficas de NVIDIA se hacen accesibles
para la computación de propósito general como lo son las CPU.
4.1. Interfaz de programación CUDA
A continuación explicaremos como se con la herramienta CUDA podemos plasmar
código que será ejecutado de forma paralela.
4.1.1. Estructura de un programa en CUDA
Una estructura en CUDA [9] consiste en una o varias fases que se ejecutan bien en el
host (CPU) o en un dispositivo (device) como puede ser la GPU. Las fases que muestran poco o
ningún paralelismo se implementan en el código dedicado al host. Por su parte, las zonas que
muestran un gran paralelismo, se implementarán en el código correspondiente a la GPU
(device). El programa en cuestión aglutina en un único código ambas zonas, quedando la labor
de separarlas para el compilador de C de NVIDIA, NVCC. El código del host se corresponde con
ANSI C tradicional y se puede compilar con los compiladores de C tradicionales, así como
ejecutarse como un proceso ordinario. El código correspondiente a la GPU, se escribe
utilizando ANSI C extendido con determinadas palabras clave para etiquetar funciones
paralelas, llamadas kernels, y sus estructuras de datos asociadas. El código para el dispositivo
(device) es compilado por el NVCC y se ejecuta en la GPU. Es posible que no exista ningún
dispositivo disponible o que, para determinados kernels sea más óptima la ejecución de éstos
en la CPU, para ello también se dispone de la posibilidad de seleccionar dónde se ejecuta cada
kernel.
Los kernels normalmente generan un gran número de threads con el fin de explotar el
paralelismo de los datos. Cabe destacar que los threads en una GPU son mucho más ligeros
que los que se generan en la CPU, es decir, no existen dependencias entre ellos y suelen
realizar determinados cálculos concretos sin demasiada ramificaciones a lo largo de la
ejecución del proceso, así se podrá suponer que la generación y organización (schedule) de los
threads en la GPU necesitará relativamente pocos ciclos de reloj debido a su alta eficiencia
hardware.
En la Figura 2-3, hemos representado la jerarquía de programación básica que habrá
que tener en mente cuando programemos. En cada thread se mapeará cada una de las N
ejecuciones en paralelo de nuestro proceso, a su vez, estos threads se agrupan en bloques (el
número de threads por bloque asignable está limitado, debido a la limitación de recursos,
Patricio López Capitulo 2. CUDA para la aceleración de
simulaciones en Matlab
Noviembre 2011
23
sobre todo la memoria compartida por bloque y los registros), y de la misma manera estas
bloques se agrupan en grids. Cada llamada a un kernel implica la generación de un grid.
Memoria
Global
Memoria
compartida
por bloque
Memoria
local por
thread
Grid
Thread blockThread
Block (0,0) Block (1,0)
Block (N,M)
Block (N,0)
Block (0,M) Block (1,M)
Figura 2-3. Jerarquía básica para la programación CUDA
En la Figura 2-4 se puede ver una ejecución típica de un programa escrito en CUDA. La
ejecución se inicia en el host (CPU). Al invocar un kernel, la ejecución se traslada a la GPU,
donde se genera un gran número de threads para aprovechar el paralelismo. El conjunto de
threads que genera un kernel durante su invocación se agrupan en los llamados grids. La Figura
2-4 muestra la ejecución de dos grids de threads. Cuando todos los threads de un kernel
completan su ejecución y por lo tanto desaparece su grid respectivo, la ejecución se continúa
en el host hasta que se invoque otro kernel.
Block (0,0) Block (1,0)
Block (0,M) Block (1,M)
Block (0,0)
Block (0,M)
Host HostDevice Device
Ejecución secuencial
del programa en C
Kernel 1 Kernel 2
Tiempo de
ejecución
Figura 2-4. Etapas en la ejecución de un programa en CUDA
Patricio López Capitulo 2. CUDA para la aceleración de
simulaciones en Matlab
Noviembre 2011
24
4.1.2. Compilación
4.1.2.1. Compilación con NVCC
Los kernels se pueden escribir utilizando el conjunto de instrucciones provistas por
CUDA, éstas se llaman PTX (Parallel thread Execution). De todas formas, es mucho más común
y sencillo utilizar programación en un nivel superior como puede ser el lenguaje C. Bien si
usamos instrucciones PTX como otro lenguaje, los kernels se deben compilar a código binario
mediante NVCC para así poder ser ejecutadas en la GPU.
NVCC es un driver de compilación que simplifica las tareas de compilación del código
PTX o C en nuestro caso. Proporciona opciones de línea de comandos y las ejecuta utilizando
las herramientas apropiadas para cada etapa en el proceso de compilación.
4.1.2.2. Compilación desde el entorno matlab
MEX Files
Nuestro objetivo es hacer interactuar un modelo de simulación en lenguaje C, para el
cual NVIDIA ha desarrollado una API (Aplication Program Interface) que nos permite utilizar los
recursos de la tarjeta gráfica (CUDA), con el resto de nuestra plataforma de simulación de
sistemas de comunicaciones, cuyo entorno es Matlab.
Para esto Matlab ofrece los mex (matlab executable) files, con los que se puede
establecer una interfaz con diferentes lenguajes de programación como son C, C++ y Fortran.
Esto permite aplicar funciones existentes en alguno de estos lenguajes y no provistas por las
librerías de Matlab y a su vez reescribir determinados procesamientos que podrían resultar un
cuello de botella en nuestra aplicación si se utilizase directamente Matlab.
Para hacer posible esta tarea, Matlab incorpora unas librerías que definen de forma
rezada la API para los ficheros mex. Éstas son: la librería MAT-File, que contiene las funciones
que posibilitan la incorporación de datos Matlab a los programas escritos en los lenguajes
anteriormente mencionados, la librería MX Matrix, que posibilita la utilización (creación y
manipulación) de matrices, y la librería MEX, que posibilita la utilización del entorno Matlab
para la ejecución de funciones en C, C++ y FORTRAN.
Además de definir la interfaz para ficheros descritos en otros lenguajes de
programación, MEX resulta en una función Matlab del mismo nombre, la cual se encarga de
compilar dichas funciones aplicando diversas opciones, fundamentalmente la selección del
compilador a utilizar, opciones de depuración, linkado, etc.
Tras la aplicación de esta orden, obtendremos un archivo ejecutable por Matlab y con
una extensión del tipo mexw32, mexw64, mexglx, mexa64... en función del tipo de
arquitectura para la que hayamos compilado.
En el caso de que nuestros ficheros contengan funciones de la API de CUDA, se ha
desarrollado otra instrucción similar adaptada a esta situación, NVMEX [10] . En este caso el
compilador utilizado será el NVCC, provisto por el entorno CUDA y la extensión de nuestro
fichero a compilar será .cu.
Patricio López Capitulo 2. CUDA para la aceleración de
simulaciones en Matlab
Noviembre 2011
25
De forma general en un fichero MEX encontraremos:
Inclusión de librería mex.h
Rutina mex para la interfaz con el fichero en C, C++, FORTRAN. Siempre será del tipo:
- mexFunction(int nlhs, mxArray *plhs[ ],int nrhs, const mxArray *prhs[ ]) { . }
- donde nlhs indica el número de parámetros de salida esperado
- plhs son los punteros a cada matriz de salida
- nrhs el número esperado de parámetros de entrada
- prhs los punteros a los parámetros de entrada
Para contener los datos Matlab todos los ficheros contendrán structuras del tipo
mxArray
A su vez se utilizarán distintas funciones de la API, como reserva de memoria,
liberación de memoria, etc)
A esta estructura general de un archivo MEX, en el caso de contener funciones para la
explotación de los recursos de la GPU, tendremos que añadir por norma las siguientes etapas
en el desarrollo de nuestro programa:
Reserva de memoria en la GPU
Copia de los datos a la GPU. Comprobar la precisión y transformar a precisión simple si
fuese necesario
Si los datos se ubican en memoria reservada con la instrucción mxMalloc, no será
posible la utilización de memoria virtual (desde el punto de vista de la GPU, pinned
memory)
Liberación de la memoria reservada en la GPU.
4.1.2.3. Compilación independiente
Aunque por supuesto estos ficheros ejecutables mex se pueden generar directamente con el
compilador que dispongamos en nuestra máquina. Eso sí, hemos de tener en cuenta las
librerías necesarias para la correcta generación del ejecutable. Mientras que trabajando con un
entorno Linux, una de las opciones más manejables es la realización de un makefile y la
utilización del archiconocido compilador gcc. En un entorno Windows hemos considerado
oportuna la utilización del entorno de programación Visual Studio, debido a la gran integración
que ofrece de las librerías de CUDA en sus últimas versiones, así como la posibilidad de
integrar el software desarrollado por NVIDIA, Parallel NSight, que permite depurar los
programas a nivel de GPU.
4.2. Consideraciones sobre la utilización de la memoria
4.2.1. Optimización
Las optimizaciones de los aspectos relacionados con la memoria son básicos para
alcanzar las máximas prestaciones [11] . El objetivo es maximizar la utilización del hardware
maximizando el ancho de banda de la memoria. Esto se consigue maximizando la utilización de
memorias rápidas y evitando los accesos a las memorias más lentas.
Patricio López Capitulo 2. CUDA para la aceleración de
simulaciones en Matlab
Noviembre 2011
26
4.2.1.1. Transferencia entre el Host y la GPU
Si realizamos una primera comparación entre la tasa de transferencia de la memoria
interna de una tarjeta NVIDIA y la que nos da el bus PCI Express podemos ver una diferencia
abismal, de unos 8 GBps a entorno 150 GBps que ofrece la GPU. Por lo que es obvio que
tendremos que evitar las transferencias entre host y device siempre que podamos. Esto quiere
decir que muchas veces convendrá ejecutar kernels en la GPU incluso si estos no aportan una
gran aceleración.
De cualquier forma, si es indispensable realizar este tipo de transferencias, siempre es
adecuado agruparlas en un solo acceso debido al overhead que implica cada transferencia de
memoria.
Como apreciación final, esta penalización en lo que se refiere a la transferencia de
memoria del Host a la GPU se puede paliar en parte con la utilización de memoria virtual desde
el punto de vista de la GPU (también llamada page locked o pinned memory), es decir una
reserva de memoria exclusiva para su utilización por determinados periféricos, en este caso la
tarjeta gráfica. Este tipo de memoria permite la realización de transacciones asíncronas de
memoria, éstas a su vez permiten solapar las transferencias de memoria con otros cálculos
realizados por la CPU e incluso los cálculos realizados por la GPU. En la Figura 2-5 vemos un
ejemplo de cómo al utilizar la copia asíncrona en memoria (para ello será necesario utilizar
métodos de CUDA que nos dan la posibilidad de controlar varios flujos mediante
identificadores), y como esto permite el solapamiento de las etapas de copia en memoria y
ejecución, obteniendo una mejora sustancial en el tiempo de ejecución.
Copiar datos en la GPU
Ejecutar algoritmo
Tiempo de ejecución
Figura 2-5. Ejemplo de copia y ejecución solapadas
4.2.1.2. Transferencias internas de la GPU
Los dispositivos CUDA utilizan diversos espacios de memoria, que a su vez tienen
distintas características apropiadas para diferentes aplicaciones. Entre estos espacios de
memoria diferenciamos la memoria global, la local, la compartida (shared), la de textura y los
registros. De todas ellas, las memorias local, global y de textura son las que tienen una latencia
de acceso mayor mientras que en este orden, la memoria constante, los registros, y la
memoria compartida son las más rápidas.
En la siguiente tabla podemos observar las características fundamentales de todos los
tipos de memoria.
Patricio López Capitulo 2. CUDA para la aceleración de
simulaciones en Matlab
Noviembre 2011
27
Tabla 2-1. Diferentes tipos de memoria en la GPU y sus características
Tipo de memoria
Localización física
Jerarquización de memoria
Acceso Alcance Tiempo de vida
Registros On chip No Lectura/Escritura 1 threads Threads
Local Externo En arq 2.x Lectura/Escritura 1 threads Threads
Compartida On chip No Lectura/Escritura Todos los threads de un bloque
Bloque
Global Externo En arq 2.x Lectura/Escritura Todos los threads y el host
Reserva desde el host
Constante Externo Sí Lectura Todos los threads y el host
Reserva desde el host
De textura Externo Sí Lectura Todos los threads y el host
Reserva desde el host
Acceso agrupado a memoria
Seguramente el aspecto más importante a tener en cuenta a la hora de programar
para la arquitectura CUDA es el agrupamiento de los accesos a la memoria global (coalesced
Access to global memory). Los procesos de lectura y escritura en la memoria global que realiza
cada thread se realizan por grupos de medio warp o incluso de un warp completo (para
dispositivos con arquitectura Fermi). El acceso de todo el grupo de threads se lleva a cabo en
una única transacción siempre que se cumplan algunos requisitos. Éstos dependen de la
versión de la arquitectura CUDA con la que estemos trabajando.
Todo esto se fundamenta en la alineación de la memoria global, estructurada en
segmentos de 16 y 32 palabras, como podemos ver en la Figura 2-6. De esta manera si
tenemos palabras de 32 bits, medio warp (16 threads) podrá acceder a 64B y con un warp
completo accederemos a grupos de 128B. Para ello partimos del hecho que las reservas de
memoria aplicando los métodos cudaMalloc nos proporcionan segmentos de memoria
alineados cada 256 bytes. De esta manera, los threads con índices consecutivos que accedan a
posiciones consecutivas y alineadas dentro de segmentos de la misma medida que un warp
tendrán una ganancia debido a la concurrencia en dicho acceso a memoria.
Patricio López Capitulo 2. CUDA para la aceleración de
simulaciones en Matlab
Noviembre 2011
28
Palabra de 32 bits
Segmento alineado de
64B
Segmento alineado de
128B
Warp de 32 threads
Figura 2-6. Alineación de la memoria global
Para los dispositivos anteriores a la versión Fermi existen requisitos más rígidos a la
hora de organizar estos accesos a memoria, en cambio para la arquitectura 2.x (Fermi), basta
con que el grupo de threads que acceden a la sección de la memoria estén alineados con el
tamaño de ésta. Esto sucede gracias a sus mejoras en términos de jerarquización de la
memoria.
Ilustramos un ejemplo de un acceso no alineado a memoria (Figura 2-7), donde el un
mismo warp accede a distintos segmentos, lo que resultará en la necesidad de realizar dos
accesos independientes a memoria.
Figura 2-7. Acceso no alineado a memoria global
Memoria Compartida
Esta memoria está situada dentro del chip del procesador gráfico, por lo que es mucho
más rápida que la memoria local y la global, este tipo de memoria tiene unas 100 veces menos
latencia que la memoria global, siempre que también se cumplan algunas pequeñas reglas de
funcionamiento.
Para alcanzar un gran ancho de banda, en accesos concurrentes, la memoria
compartida se divide en módulos de igual tamaño llamados bancos (Banks) a los que se puede
acceder simultáneamente. Por lo tanto cualquier acceso a memoria (sea en lectura o escritura)
desde n direcciones de memoria que se mapeen en n bancos de memoria distintos se
realizarán de forma simultánea, radicando en un ancho de bando efectivo n veces mayor que
si se accediese a un único banco.
Patricio López Capitulo 2. CUDA para la aceleración de
simulaciones en Matlab
Noviembre 2011
29
Por otro lado, si diversas direcciones de memoria acceden sobre el mismo banco los
accesos se serializan. A esto se le llaman bank conflicts, y hace disminuir ostensiblemente la
ganancia en ancho de banda de nuestras transferencias de memoria. Aunque existen
excepciones a la hora de realizar lecturas del tipo broadcast o multicast (varios threads
necesitan la misma información).
Los bancos de la memoria compartida se organizan de manera que palabras sucesivas
de 32 bits se asignan a bancos consecutivos y cada banco tiene un ancho de banda de 32 bits
por ciclo de reloj.
Para los dispositivos de capacidad 1.x, el tamaño del warp es de 32 threads y el
número de bancos es 16. Por lo que el acceso a memoria de un warp completo se divide en
dos fases. En dispositivos Fermi el número de bancos es de 32, por lo que el acceso de un warp
no se divide, por lo que habrá que tener en cuenta posibles conflictos entre los hilos de todo el
warp.
Memoria Local
La memoria local recibe su nombre porque su alcance es único para cada thread, no
por su localización, ya que se encuentra fuera del chip. Por lo que acceder a la memoria local
penaliza tanto como acceder a la memoria global.
La memoria local se utiliza únicamente para mantener variables automáticas. Tareas
llevadas a cabo por el compilador si “ve” que no hay espacio suficiente en la memoria
registrada.
Memoria de textura (Texture memory)
Se trata de una memoria de sólo lectura y con acceso a través de una estructura caché.
Por lo que recoger un dato de dicha memoria no tiene coste alguno (en el caso de estar en la
caché). La estructura de la memoria caché está optimizada para accesos localizados en un
espacio bidimensional dentro de su estructura de manera que los threads de un mismo warp
que lean direcciones de memoria cercanas, nos darán grandes velocidades de acceso.
Memoria constante (Constant memory)
La cantidad de memoria constante en nuestro dispositivo es relativamente pequeña,
disponemos de un total de 64KB. El acceso a esta memoria tiene una jerarquización caché.
Como resultado, un acceso en lectura a la memoria constante, sólo se produce un coste real si
esta operación no se encuentra en la caché. Para todos los threads de medio warp el acceso a
memoria constante es tan rápido como acceder a los registros siempre que todos los threads
accedan a la misma dirección de memoria. Los accesos a diferentes direcciones de memoria se
serializan, por lo que el coste crece linealmente con el número de direcciones distintas a las
que accedamos dentro de medio warp.
Registros
Normalmente, el acceso a un registro no consume ningún ciclo de reloj extra en el
proceso de ejecución de una instrucción, aunque en algunos casos se pueden dar retrasos
Patricio López Capitulo 2. CUDA para la aceleración de
simulaciones en Matlab
Noviembre 2011
30
debido a dependencias del tipo “leer después de escribir” o conflictos en los bancos de
memoria.
La latencia producida por la dependencia “leer después de escribir” es de unos 24
ciclos de reloj, pero este retardo se enmascara completamente en multiprocesadores con al
menos 192 threads activos (equivalente a 6 warps) para el caso de dispositivos de capacidad
1.x (éstos tenían 8 CUDA cores por multiprocesador (8 cores * 24 ciclos de latencia = 192
threads necesarios para cubrir ese retardo). En el caso de dispositivos de capacidad 2.x, se
requieren al menos 768 threads activos para enmascarar dicha latencia, ya que cada
multiprocesador consta de 32 CUDA cores.
El compilador y el organizador hardware de los threads secuenciará las instrucciones
de la forma más óptima posible para evitar conflictos con los bancos de memoria de los
registros. Éstos alcanzan las mejores prestaciones cuando el número de threads por bloque es
múltiplo de 64. En el caso de no seguir esta regla, la aplicación no tiene control directo sobre
dichos conflictos.
4.2.2. Reserva de memoria
Las operaciones de reserve y liberación de recursos de memoria, normalmente
realizadas a través de las funciones proporcionadas por la API de CUDA cudaMalloc() y
cudaFree(), son operaciones con un gran coste, por lo que es conveniente reutilizar la memoria
ya reservada en la GPU siempre que sea posible, de manera que limitemos el impacto de estas
reservas de memoria sobre las prestaciones globales de nuestro sistema.
4.3. Obtención de las máximas prestaciones
La ganancia que obtendremos de la aplicación de CUDA depende completamente del
nivel de paralelización al que podamos llegar. De esta forma, un código que no pueda ser
fuertemente paralelizable se deberá ejecutar en el Host, a menos que la trasferencia de datos
de una memoria a otra se convierta en un cuello de botella.
La ley de Amdahl [12] establece la aceleración máxima que se puede esperar al
paralelizar la ejecución en serie de un determinado programa:
Eq. 1
Donde P representa el porcentaje de código que se puede paralelizar, medido sobre el
tiempo total de ejecución del programa en serie y N el número de procesadores sobre los que
podemos ejecutar dicha sección de código paralelizable. De esta manera si el número de
procesadores es extremadamente grande la expresión quedará en . Esto es, si
sólo podemos paralelizar las tres cuartas partes de nuestro código, por muchos procesadores
que tengamos, nunca conseguiremos acelerar la ejecución más de 4 veces.
Patricio López Capitulo 2. CUDA para la aceleración de
simulaciones en Matlab
Noviembre 2011
31
4.4. Consideraciones sobre la arquitectura Fermi de NVIDIA
De las recomendaciones de NVIDIA [11] para una programación y concepción óptima
de la solución a nuestro problema, se concluye que lo principal es:
Buscar la forma de paralelizar el código secuencial
Minimizar las transferencias de datos entre el host y la GPU
Ajustar el diseño de los kernel para maximizar la utilización de los recursos de
la GPU
Asegurar que los accesos a la memoria global se realizan de manera contigua
Reemplazar los accesos a memoria global por accesos a memoria compartida
siempre que sea posible
Evitar bifurcaciones en el código y distintos caminos de ejecución dentro del
mismo warp
En general, la arquitectura de CUDA 2.0 [13] proporciona una mayor flexibilidad, ya
que permite la ejecución de distintos kernels de forma concurrente facilitando el
aprovechamiento de toda la capacidad de la GPU.
Los dispositivos con arquitectura Fermi incorporan una memoria cache jerarquizada
con el fin de descargar de accesos a la memoria global y compartida. El programador puede
repartir la capacidad de memoria entre la memoria compartida y la memoria cache L1 (primer
nivel de jerarquización de la memoria cache). A su vez, se puede desactivar la intervención de
la memoria cache L1 sobre la memoria global (la intervención sobre la memoria local no se
puede desactivar, aunque sí se puede limitar el número de variables que el compilador puede
ubicar en esta memoria local).
Es importante recordar que en la arquitectura 1.x de CUDA, los accesos a la memoria
global se procesaban de medio en medio warp. Por el contrario, en los dispositivos Fermi estos
accesos se procesan con el warp completo. Esto se debe tener en cuenta a la hora de asignar el
número de threads por bloque, ya que en versiones anteriores se debía escoger un múltiplo
del número de threads en medio warp, mientras que ahora se trata del warp completo.
En lo que se refiere a la memoria compartida, en los dispositivos Fermi, podemos
reservar hasta 3 veces más de memoria, permitiendo ampliar el número de bloques por
multiprocesador y desplazando la memoria compartida como factor limitante de las
prestaciones. También cambia la estructura de la memoria compartida, pasando a tener de 16
a 32 bancos (lo que permite realizar los accesos por warps completos, como hemos
mencionado antes). Esto provoca que puedan ocurrir conflictos de acceso entre threads
pertenecientes a distintas mitades del warp, por lo que es necesario un reajuste de dichos
accesos.
Patricio López Capitulo 2. CUDA para la aceleración de
simulaciones en Matlab
Noviembre 2011
32
Jerarquización de la memoria en la arquitectura Fermi
Memoria
compartidaCache L1
Cache L2
DRAM
Figura 2-8. Jerarquización de la memoria en la arquitectura Fermi
4.4.1. Comunicación de los threads dentro de un mismo warp
El intercambio de información entre threads se puede realizar por medio de la
memoria compartida o la memoria global. Normalmente, con el fin de optimizar, se omite la
sincronización de los resultados producidos por los warps (syncthreadss()), ya que dentro de
un warp se asegura un total sincronismo.
Una aplicación típica de esta optimización son las reducciones en paralelo, en concreto
aquellas en las que cada salida depende de todas las entradas (suma de elementos,
búsquedas...).
En el caso de que en nuestros kernels los threads dentro de un warp se intercambien
información a través de la memoria global o compartida, es fundamental que el puntero a esa
zona de memoria sea declarado como volatile, de manera que se fuerce al compilador a sacar
los valores a la memoria (sea global o compartida) [14] ya que en caso contrario se optimizará
para la arquitectura Fermi, manteniendo estos valores en registros internos.
5. Conclusión
Hemos analizado una de las herramientas disponibles para la programación paralela
haciendo uso de los recursos proporcionados por la tarjeta gráfica. De la misma manera se
presenta una solución para el desarrollo de este tipo de trabajo integrando el entorno CUDA y
la plataforma de simulación la cual se ejecuta en Matlab.
Por lo que tomamos la solución Matlab + CUDA como punto de partida para la
implementación de los algortitmos paralelizados propuestos.
Capítulo 3. Turbo Códigos
1. INTRODUCCIÓN ..................................................................................................................... 34
2. LOS TURBO CÓDIGOS ............................................................................................................. 35
2.1. Proceso de codificación ........................................................................................... 35
3. PROCESO DE DECODIFICACIÓN ................................................................................................. 36
3.1. Decodificadores SISO ............................................................................................... 37 3.1.1. SOVA ................................................................................................................................ 38 3.1.2. Algoritmo BCJR ................................................................................................................. 38
3.1.2.1. Algoritmo BCJR para códigos sistemáticos ............................................................... 41 Formulación LLR del algoritmo ............................................................................................. 42 Aproximación por el máximo. Max-Log-MAP ....................................................................... 43
4. TURBO CÓDIGOS M-ARIOS ...................................................................................................... 44
4.1. Ventajas de los Turbo Códigos m-arios.................................................................... 45
4.2. Algoritmo MAP para los Turbo Códigos m-arios ..................................................... 46
5. DOS CASOS CONCRETOS .......................................................................................................... 47
5.1. Turbo código de DVB-SH .......................................................................................... 47
5.2. Turbo código de DVB-RCS ........................................................................................ 48
5.3. Comparativa ............................................................................................................ 49
6. CONCLUSIÓN ........................................................................................................................ 49
Patricio López Capitulo 3. Turbo Códigos
Noviembre 2011
34
1. Introducción
En el campo de las telecomunicaciones y teoría de la información, la función de
corrección de errores en el receptor (FEC, Forward Error Correction), también llamada
codificación de canal es un mecanismo de control de la transmisión de datos, donde el
transmisor “añade” de forma automática información redundante en sus mensajes. Richard
Hamming [15] fue pionero en este campo con la introducción de los primeros códigos FEC
(códigos Hamming, 1950).
El diseño adecuado de esta redundancia permite que el receptor pueda detectar y
corregir un número determinado de errores ubicados en cualquier lugar del mensaje sin la
necesidad de realizar peticiones de reenvío al transmisor. Aunque esta capacidad se consigue a
costa la pérdida de algo del ancho de banda debido a esta codificación de canal aplicada. Las
técnicas FEC se aplican en sistemas donde la retransmisión de información es costosa, esto se
da en sistemas de difusión (broadcasting y multicasting).
Las distintas técnicas FEC se pueden dividir fundamentalmente en dos grupos:
Los códigos de bloques, que trabajan sobre paquetes o grupos de bits o
símbolos de un tamaño predeterminado
Códigos convolucionales que trabajan a nivel de bit o flujo de símbolos de una
longitud arbitraria. El algoritmo más utilizado para la decodificación de este
tipo de códigos es el de Viterbi. Su eficiencia crece asintóticamente con la
longitud del registro que lo conforme aunque su complejidad crece
exponencialmente con ésta.
En la actualidad destacan fundamentalmente dos tipos de codificación, las cuales se
quedan muy cerca del límite teórico de Shannon para la capacidad del canal, aunque su
decodificación iterativa hace que sean muy exigentes computacionalmente. En estos últimos
años los requisitos en términos de capacidad de canal han crecido notablemente y como
consecuencia se han desarrollado los dos tipos de codificaciones fundamentales que
actualmente abarcan prácticamente todos los sistemas de comunicaciones de banda ancha,
estos son los Turbo Códigos [6] y los códigos LDPC [5] (Low Density Parity Check).
Tanto los Turbo Códigos como los LDPC proporcionan prestaciones similares [16] [17] ,
aunque analizando su complejidad y versatilidad, los LDPC son más apropiados para palabras
de código de mayor longitud y code rates mayores, mientras que los Turbo Códigos ganan
enteros en sistemas con palabras de código más cortas y code rates más robustos.
Además, los Turbo Códigos ofrecen mejor capacidad de adaptación a diferentes tasas
de transmisión. Debido a sus características los Turbo Códigos son especialmente apropiados
para comunicaciones vía satélite.
En este capítulo describiremos el funcionamiento general de los Turbo Códigos, tanto
su proceso de codificación como el de decodificación, tema que nos ocupa en este proyecto.
Dentro del proceso de decodificación describiremos con detalle el algoritmo iterativo utilizado
para ello, ya que nuestro objetivo es paralelizar y acelerar la ejecución software del mismo.
Patricio López Capitulo 3. Turbo Códigos
Noviembre 2011
35
Posteriormente, a lo largo del capítulo también desarrollaremos los dos grandes
bloques fundamentales en los que se pueden subdividir los Turbo Códigos, estos son, los
binarios y los m-arios, de los que analizaremos sus diferencias, ventajas e inconvenientes.
Por último introduciremos dos sistemas que utilizan este tipo de codificación, DVB-SH
[18] y DVB-RCS [19] , en los que podemos ver un ejemplo de los TC anteriormente
mencionados.
2. Los Turbo Códigos
De acuerdo con Shannon, el código perfecto sería aquel en el que un mensaje se envía
infinitas veces, cada una de ellas barajado de forma totalmente aleatoria. De esta forma, el
receptor tendría infinitas versiones del mensaje, muchas de ellas con errores. De esas copias,
el decodificador es capaz de obtener con casi total perfección (libre de errores) el mensaje
enviado inicialmente.
Los Turbo Códigos se inclinan hacia esa dirección, pero lógicamente, para un
funcionamiento aceptable no necesitamos enviar infinitas versiones de nuestro mensaje. Se
comprueba que con un par de versiones o tres, es suficiente para conseguir resultados
decentes en los canales terrestres.
En los Turbo Códigos, particularmente en su estructura paralela, son los codificadores
convolucionales los utilizados para conseguir dichas versiones aleatorias del mensaje.
Esta estructura paralela utiliza dos codificadores RSC (Recursive Systematic
Convolutional), cada uno con un interleaver distinto. El objetivo de los interleavers es producir
dos versiones no correladas (o lo menos posible), resultando en bits de paridad por cada RSC
totalmente independientes entre ellos. “Cómo” de independientes sean estos bits de paridad
depende exclusivamente de la profundidad y el correcto diseño de los interleavers (longitud y
profundidad). En un código Viterbi [20] típico, los mensajes se suelen decodificar en bloques
de unos 200 bits, mientras que en los turbo códigos se puede llegar al palabras de 16k bits.
El proceso de codificación consiste en dos o más códigos sistemáticos por bloques que
comparten el mensaje a codificar a través de unos interleavers. En su realización típica las
palabras de código se obtienen a partir de códigos convolucionales recursivos (RSC). La clave
de los turbo códigos es la posibilidad de realizar su decodificación mediante un proceso
iterativo. En este proceso, los decodificadores (uno por cada codificador presente en el
encoder) se turnan operando sobre los datos recibidos. Cada decodificador produce una
estimación de las probabilidades de los símbolos transmitidos. Para hacer efectiva este
proceso es necesario que los decodificadores sean tipo SISO (Soft Input, Soft Output).
2.1. Proceso de codificación
En la Figura 3-1 se muestra el esquema básico de un turbo codificador [6] (sin
puncturing, etapa opcional para dar mayor versatilidad de tasa de transmisión). Consiste en
dos funciones de transferencia que representan las componentes no sistemáticas de los
codificadores convolucionales recursivos (RSC) y de un interleaver ( representa la matriz de
permutación del interleaver), que permuta los símbolos de entrada y que se transfieren al
Patricio López Capitulo 3. Turbo Códigos
Noviembre 2011
36
segundo codificador RSC. Normalmente, los codificadores convolucionales tienen un mejor
funcionamiento cuando su función de transferencia contempla una realimentación, lo que se
traduce en una función de transferencia racional.
RSC encoder
RSC encoder
x
v(0)
v(1)
v(2)
Figura 3-1. Estructura básica de un Turbo Código de bloques y paralelo
No existe ninguna razón para que la función de transferencia de ambos codificadores
sea la misma, pero hasta ahora se ha probado un funcionamiento óptimo con la utilización de
exactamente la misma función de transferencia.
El funcionamiento es el siguiente:
tomemos como entrada un conjunto de símbolos (del tamaño de la palabra
de código), normalmente cada símbolo representa el bit o conjunto de bits
(alfabeto) que sirven como información sistemática para los codificadores.
Cada bloque de símbolos de entrada se suele terminar con una secuencia para
llevar los codificadores al estado 0.
se utiliza en primer lugar para, de forma directa, transmitir a la salida la
información sistemática, que llamaremos
Esta entrada también alimenta directamente el primer codificador RSC que
producirá una secuencia de paridad .
Por último, se aplicará al segundo codificador (en paralelo) previo
entrelazado de los símbolos que lo componen, produciendo una segunda
secuencia de paridad .
Finalmente multiplexaremos , y para su posterior modulación y
transmisión.
3. Proceso de decodificación
[21] Tras transmitir los datos codificados y multiplexados , recibiremos una secuencia
también modificada por el canal de transmisión del que conste nuestro sistema de
comunicaciones. En podremos diferenciar también la parte correspondiente a la información
sistemática, en el receptor nos referiremos a ella como y de forma análoga tendremos la
información recibida correspondiente a ambas secuencias de paridad y .
Patricio López Capitulo 3. Turbo Códigos
Noviembre 2011
37
Decodificador
SISO
Decodificador
SISO
1
Información sistemática
Paridad 1er RSC
Paridad del 2º RSC
LintrinsicLintrinsic
Lextrinsic
Lextrinsic
Valor inicial
r(0)
r(2)
r(1)
Figura 3-2. Esquema básico Turbo Decoder
De la estructura del Turbo Coder, se puede derivar una arquitectura lógica para el
proceso de decodificación. Asociaremos al primer decodificador la información recibida y
(correspondiente a la información sistemática; sin entrelazar y a la primera secuencia de
paridad, producida por el primer RSC) y al segundo decodificador le asociaremos (ya
que esta información se insertó con una permutación previa en el segundo encoder) y .
(Correspondiente a la secuencia de paridad generada por el segundo codificador RSC).
El primer decodificador utiliza la información a priori asociada a los bits transmitidos y
produce probabilidades de cada símbolo (bit o conjunto de bits) condicionadas a los datos
observados. A estas probabilidades se les llama información extrínseca. Las probabilidades de
salida producidas por el primer decoder se pasan por el entrelazador y sirven como
probabilidades a priori para el segundo decoder. Así de forma iterativa, a la salida del segundo
decoder se le aplica la función inversa del interleaver para aplicarse como entrada de
nuevo al primer decoder.
Este proceso se repite hasta que cumplimos algún criterio de convergencia o
simplemente se alcanza un número límite de iteraciones.
Por lo tanto, los componentes fundamentales del proceso de decodificación son los
algoritmos capaces de proporcionar las probabilidades a posteriori para cada símbolo de
entrada. El algoritmo más utilizado es el MAP (Maximum A Posteriori), también conocido como
BCJR. Aunque también encontramos el SOVA (Soft-Output Viterbi Algorithm) con una
complejidad menor aunque con unas prestaciones ligeramente menores.
3.1. Decodificadores SISO
Tras describir la arquitectura del decodificador, llegamos a la conclusión de que el
componente fundamental del algoritmo iterativo explicado son los decodificadores
encargados de proporcionar las estimaciones de la probabilidad a posteriori de los bits (o
grupos de bits) de entrada. El algoritmo más utilizado para esta decodificación soft es el
llamado algoritmo MAP, también conocido como BCJR. Las métricas que utiliza el algoritmo
MAP se pueden expresar en función del algoritmo de la probabilidad. También se ha
desarrollado una adaptación directa del algoritmo de Viterbi para disponer de estos valores
soft, en este caso tenemos como resultado una complejidad menor, aunque también peores
Patricio López Capitulo 3. Turbo Códigos
Noviembre 2011
38
prestaciones en relación con el algoritmo MAP. A continuación pasamos a describir estos dos
algoritmos fundamentales.
3.1.1. SOVA
El algoritmo "Soft Output Viterbi Algorithm" [22] (SOVA) se diferencia del algoritmo de
Viterbi clásico en que éste utiliza una métrica modificada que tiene en cuenta las
probabilidades a priori de los símbolos de entrada y además produce una salida soft que indica
la fiabilidad de la decisión tomada a la salida.
Si se considera el modo de operación normal del algoritmo de Viterbi. En un instante t,
cada camino “superviviente” implica una serie de operaciones suma-comparación-selección
(ACS, Add, Compare and Select), cada una resultando en la selección de un valor para cada
símbolo o bit de información. Por lo tanto partimos de la premisa de que el algoritmo de
Viterbi es óptimo y nos da la secuencia de estados de menor coste, es óptimo en el sentido
ML (Maximum Likelihood). Hagenauer y Hoeher exponen que la probabilidad de que un valor
dado sea correcto, es proporcional a cómo de “cerca” quedó la selección de éste respecto de
los otros valores posibles. Dando como fruto el llamado algoritmo SOVA.
El objetivo de este proyecto no se centra en la implementación de este algoritmo, por
lo que no profundizaremos en su explicación y nos limitaremos a sus referencias por interés
del lector.
3.1.2. Algoritmo BCJR
También conocido como el algoritmo MAP [23] (Maximum A Posteriori) se basa en la
interpretación de la codificación como un proceso de Markov. El algoritmo BCJR (llamado así
por sus creadores, Bahl, Cock, Jelenik and Raviv) computa las probabilidades a posteriori de los
símbolos provenientes de las fuentes de Markov, transmitidas a través de canales discretos sin
memoria. Como la salida del codificador convolucional afectada por un canal sin memoria
conforma una fuente de Markov, el algoritmo BCJR se puede utilizar para una decodificación
de los códigos convolucionales basada en la máxima probabilidad a posteriori. Esta
decodificación es similar en muchos aspectos al algoritmo de Viterbi, teniendo en cuenta claro,
que el algoritmo clásico de Viterbi sólo proporciona valores hard (aunque esté utilizando
métricas para las ramas, ya que sólo se selecciona una rama posible para cada estado en cada
instante de tiempo). El resultado de la decodificación viterbi es una decisión global sobre la
secuencia completa de bits y no existe la posibilidad de conocer la fiabilidad de cada bit (o
conjunto de bits en el caso de que se trate de un codificador m-ario), además, las métricas
asociadas a cada rama no dependen de la información a priori sino simplemente de las
probabilidades (en este caso log-likelihood). Por el contrario, el algoritmo BCJR asigna una
probabilidad a posteriori asociada a la fiabilidad de la secuencia de salida dada una secuencia
observada (curiosamente, esta secuencia no tiene por qué coincidir con un camino continuo a
lo largo del trellis).
Para describir el funcionamiento del algoritmo MAP, definiremos el codificador
convolucional, representado mediante un diagrama de trellis, un mensaje de entrada, cuyos
bits se agrupan en símbolos formando palabras con tantos bits como bits de entrada tenga el
codificador para cada instante de tiempo (en el caso de que sea binario, esto se traducirá en
una modulación BPSK, para dos bits de entrada estos valores vendrán representados por una
Patricio López Capitulo 3. Turbo Códigos
Noviembre 2011
39
QPSK, para tres una 8-PSK y así sucesivamente). De esta forma podemos representar una
muestra del proceso de codificación.
t t+1
pt
qt 1
xt / at
r<t rt r>t
Figura 3-3. Muestra del trellis del proceso de codificación
En la Figura 3-3, y , representan el estado en el instante t y t+1
respectivamente. representa la salida mapeada en la constelación correspondiente dada
una entrada posible del alfabeto .
El objetivo del decoder MAP es proporcionar las probabilidades a posteriori de la
entrada , es decir, la probabilidad de que la entrada fuese algún valor en un
instante de tiempo condicionada a la secuencia recibida completa . El algoritmo BCJR nos
facilita una forma eficiente para calcular estas probabilidades. El primer paso es calcular las
probabilidades asociadas a los estados, una vez determinadas éstas, el cálculo de la
probabilidad de cada bit es inmediato.
Para aprovechar las propiedades Markovianas de los códigos convolucionales podemos
representar la secuencia recibida dividida en tres subconjuntos,
Donde representa el conjunto de observaciones previas al instante t, se
corresponde con la observación “actual” y es el conjunto de observaciones futuras.
Por lo tanto, la probabilidad a posteriori de una transición dada la
secuencia observada viene dada por:
Donde representa la probabilidad y es la función de densidad de probabilidad.
Aplicando factorización condicional y aprovechando las propiedades markovianas del
proceso, esta probabilidad se puede escribir como:
Patricio López Capitulo 3. Turbo Códigos
Noviembre 2011
40
Donde podemos diferenciar tres factores que marcarán la naturaleza del algoritmo de
decodificación:
1. .
Que representa la probabilidad de las observaciones hasta el instante ,
con terminación en el estado en el instante de tiempo .
2.
Es la probabilidad de la transición del estado al tomando como instante
de observación.
3.
Es la probabilidad de la secuencia observada futura , teniendo en cuenta
que esta comienza en el estado en el instante
De esta manera obtendremos la probabilidad de cada estado,
Si denotamos como el conjunto de posibles transiciones que se definen en el trellis
de cada uno de los codificadores convolucionales que conforman el Turbo Encoder, donde
para cada valor posible de entrada y estado (de los definidos en el alfabeto, en el caso binario
0 y 1) se define una única posible transición, la probabilidad a posteriori queda definida por la
expresión,
Eq. 1
Donde se ha asumido que el trellis es invariante en el tiempo. El factor no es
más que un factor de normalización que no es necesario tener en cuenta para el desarrollo del
algoritmo de decodificación en sí.
De la expresión expuesta con anterioridad vemos con claridad que el desarrollo del
algoritmo BCJR requerirá del cálculo de las , y para cada estado e
instante de tiempo, lo que finalmente nos proporcionará una métrica que nos dé una idea de
la fiabilidad de la salida estimada.
Se deriva fácilmente una expresión para el cálculo de las métricas. Donde para el
cálculo de las , también llamadas Forward Metrics, ya que su cálculo implica un cómputo
iterativo de éstas desde el instante inicial del trellis hasta el instante en cuestión.
Eq. 2
Patricio López Capitulo 3. Turbo Códigos
Noviembre 2011
41
De la misma manera se deriva el cálculo de las , también llamadas Backward metrics,
pues su cómputo precisa un cálculo iterativo de las mismas desde el instante final del trellis
hasta el instante de interés.
Eq. 3
El cálculo de las métricas asociadas a las transiciones y necesarias tanto para el
cálculo de las y como de la probabilidad final de salida, no depende de instantes
posteriores ni anteriores, simplemente depende de la naturaleza del canal y de la ponderación
que asignemos a las transiciones en función del dato recibido estimado. Así el cálculo de las ,
también llamadas Transition Metrics, se puede dividir en dos factores,
Eq. 4
Una probabilidad asociada simplemente a la transición
Y una función de densidad de probabilidad que incluye los efectos del canal
En este caso derivamos la expresión para un canal AWGN.
A continuación pasamos a particularizar el algoritmo descrito para la situación
concreta de encontrarnos con codificadores convolucionales RSC, en cuyo caso las expresiones
se hacen más intuitivas.
3.1.2.1. Algoritmo BCJR para códigos sistemáticos
El algoritmo BCJR para códigos sistemáticos se expresa de una forma específica, ya que
en la salida del decodificador dispondremos de exactamente los mismos bits que a la entrada
más una información de paridad intercalada.
Por ello, si por ejemplo utilizamos un codificador 1/2 sistemático, podremos expresar
su salida como
, ya que la información transmitida en la primera
salida del codificador será exactamente la entrada. De la misma manera, la señal recibida se
podrá representar también por su parte sistemática y de paridad
.
De esta manera la probabilidad para las transiciones se puede escribir
descomponiéndola en sus partes sistemática y de paridad
Patricio López Capitulo 3. Turbo Códigos
Noviembre 2011
42
Dado que
y
son condicionalmente independientes, ya que
depende
exclusivamente de los datos de entrada y no del estado. Desarrollando la expresión general
obtenida para las probabilidades, podemos descomponerla en tres factores:
Donde es la probabilidad sistemática, asociada a dicha información. Esta
métrica está explícitamente disponible con la medida de
. Se trata de una probabilidad a
posteriori.
Eq. 5
es la información a priori, asociada sencillamente a la información transmitida.
Esto es, la información disponible sobre los bits transmitidos justo antes de que se realice
ningún tipo de codificación. También se llama información intrínseca. En el proceso iterativo
que se aplica en los Turbo Códigos dicha información a priori se obtiene del resultado del otro
decodificador del que consta el turbo decoder.
Eq. 6
Y es la probabilidad extrínseca. Se trata de la información producida por el
decoder a partir de la secuencia recibida y de la información a priori, pero excluyendo la
información aportada por los bits sistemáticos y la información a priori relacionada con el bit
. De este modo vemos que la información extrínseca no depende de si no solamente de
los datos recibidos en otros instantes de tiempo. Es en definitiva la información que se pasan
los decoders en el proceso iterativo como información a priori para el “otro” decoder.
Eq. 7
Una vez definidas estas expresiones, fundamentales para el entendimiento y
desarrollo del algoritmo BCJR, pasamos a dar una breve explicación del mismo.
Formulación LLR del algoritmo
El objetivo de nuestro algoritmo será obtener métricas del tipo LLR (Log Likelihood
Ratio), donde para el caso binario se definen de la siguiente manera.
Eq. 8
De las expresiones anteriores derivamos el cálculo de estas métricas a partir de las ,
, y . Donde la siguiente expresión representa en el numerador todas las métricas asociadas
a transiciones producidas por valores de entrada tomando el valor 1, mientras que en el
denominador, el cálculo abarca las métricas asociadas al bit 0.
Eq. 9
Patricio López Capitulo 3. Turbo Códigos
Noviembre 2011
43
Descomponiendo el logaritmo del producto, en la expresión anterior, podemos
diferenciar la contribución de tres factores
En primer lugar tenemos las probabilidades a posteriori asociadas a los bits
sistemáticos
Eq. 10
Seguidamente observamos la contribución de las probabilidades a priori, en su versión
LLR.
Eq. 11
Por último diferenciamos la contribución de la información extrínseca, que será la que
pasemos al otro decoder como información a priori
Eq. 12
Así obtenemos la expresión fundamental para el intercambio de información entre los
dos decodificadores.
Eq. 13
Extendiendo la formulación de las probabilidades como LLR a todas las métricas
presentes el algoritmo BCJR, tenemos las correspondientes para las , , y . De forma que su
evaluación será mucho más ligera computacionalmente, ya que ahora todo se basa en
operaciones aditivas.
Aproximación por el máximo. Max-Log-MAP
Y aproximando por el máximo la suma de exponenciales, tenemos, para y
Patricio López Capitulo 3. Turbo Códigos
Noviembre 2011
44
El cálculo de las métricas de las transiciones se puede expresar como la adición de las
contribuciones de las probabilidades a priori, información sistemática y de paridad.
Y por último el cálculo de los LLR de salida a partir de las métricas anteriores se define
como
Donde aplicando de nuevo la aproximación por el máximo tenemos,
Es importante notar que la aproximación por el máximo introduce una pérdida que es
paliable en cierta medida mediante una corrección de la función de la aproximación. Ver
anexo.
4. Turbo códigos M-arios
Los Turbo códigos M-arios [24] se construyen a partir de la concatenación en paralelo
de dos o más codificadores convolucionales recursivos y sistemáticos, cada uno con m bits de
entrada. Las ventaja de esta construcción, comparada con la de los Turbo Códigos clásica
(m=1) son por ejemplo una mejor convergencia de la decodificación iterativa, distancias
mínimas mayores, menor sensibilidad ante los distintos patrones de puncturing, menor
latencia y mayor robustez contra las no idealidades introducidas por las diferentes
aproximaciones que se aplican normalmente en el proceso de decodificación para reducir su
complejidad, como lo es normalmente la aproximación por el máximo en el algoritmo MAP
(Maximum a posteriori).
El caso de los codificadores duo binarios, es decir m=2, ya se ha adoptado en distintos
estándares, uno de ellos en la especificación para el canal de retorno en las redes satélites de
DVB-RCS. Estos turbo códigos, combinados con codificadores convolucionales recursivos
circulares, consiguen unas muy buenas prestaciones con tamaños de palabra desde 12 hasta
216 bytes y diversos code rates (entre 1/3 y 6/7), a la vez que mantienen una complejidad
computacional razonable.
Patricio López Capitulo 3. Turbo Códigos
Noviembre 2011
45
El esquema general de los Turbo Códigos m-arios se puede representar de la siguiente
manera, donde podemos ver dos codificadores RSC con palabras de entrada de m bits y un
interleaving que trabaja también en grupos de m bits. Por lo que los rates obtenidos con esta
codificación (obviamente, de forma previa a un posible puncturing) serán del tipo m/(m+2). A
su vez, como ya hemos mencionado, estos codificadores suelen ser circulares, lo que implica
que no se necesite ninguna secuencia de terminación para llevar al trellis a un estado
conocido.
Codificador RSC
M-ario
Codificador RSC
M-ario
Permutación
de m bits
m bits
1
1
Datos de
entrada
Parte
sistemática
Parte de
paridad
Figura 3-4. Esquema de un Turbo Código M-ario
En el punto siguiente resumimos por lo tanto las principales ventajas de los Turbo
Códigos m-arios.
4.1. Ventajas de los Turbo Códigos m-arios
Las ventajas de los Turbo Códigos M-arios [25] , tomando como punto de partida las
realizaciones binarias clásicas son:
Mejor convergencia. En este tipo de arquitectura obtenemos una densidad de
caminos erróneos menor, con lo que reducimos los efectos de la correlación
entre ambos codificadores que componen la estructura del Turbo Código. Esta
ganancia se hace muy visible si comparamos binarios y duo binarios, en
cambio no es un factor tan diferenciador para m mayores.
Distancias mínimas mayores. Esta estructura añade un grado más en la
permutación, pudiéndose realizar permutaciones intra-símbolo.
Menor sensibilidad ante los distintos patrones de puncturing. Ya que para
obtener tasas de transmisión mayores la proporción de símbolos que es
necesario descartar es menor.
Menor latencia. La latencia se divide m veces, ya que procesamos conjuntos de
m bits.
Mejor robustez del turbo decoder. Las pérdidas producidas por las
aproximaciones a los diferentes algoritmos de decodificación MAP y SOVA se
reducen. Estas pérdidas, para un turbo código binario podían variar entre 0.2 y
0.6 dB (simplificaciones como la aproximación por el máximo). Estas pérdidas
Patricio López Capitulo 3. Turbo Códigos
Noviembre 2011
46
se reducen a la mitad al aplicar un código duo binario, y aún más en códigos de
órdenes mayores (m>2). Esta mejora se da gracias a la reducción en el número
de niveles del trellis, dado que se procesan grupos de m bits simultáneamente
y la solución se aproxima más a la solución ML (Maximum Likelihood).
4.2. Algoritmo MAP para los Turbo Códigos m-arios
Las expresiones para los códigos m-arios son claramente una extensión de las
obtenidas para los códigos binarios.
Simplemente hemos de tener en cuenta que ahora el número de ramas salientes (y
por consecuente también entrantes) a cada estado se corresponderá con 2m ramas, cada una
asociada a una palabra del alfabeto formado por los m bits. De modo que nuestro decoder
deberá producir en la salida 2m -1 métricas, todas respecto a la métrica 0 (normalmente la
correspondiente a la palabra con todos los bits a 0.
Figura 3-5. Trellis correspondiente al CRSC del Turbo Código de DVB-RCS
Para el cálculo de las y tendremos que sumar además las contribuciones de todas
las ramas.
Por supuesto los códigos m-arios también admiten una formulación LLR quedando el
cálculo de las métricas de la siguiente manera
Patricio López Capitulo 3. Turbo Códigos
Noviembre 2011
47
Tabla 3-1. Expresiones de las métricas para el decoder binario y m-ario
Binario m-ario
,
,
LLR
5. Dos casos concretos
5.1. Turbo código de DVB-SH
El turbo código de SH [18] trabaja con palabras de 12282 bits, básicamente 8 paquetes
MPEG con algún overhead de señalización y CRC. Está formado por dos codificadores RSC de
tasa 1/3, por lo que por cada bit de entrada tendremos él mismo (bit sistemático) más otros
dos de paridad.
Los dos codificadores se interconectan a través de un interleaver ya anteriormente
definido para 3GPP2.
RSC de 8
estados
RSC de 8
estados
Interleaver
3GPP2
Pu
nctu
rin
g
Datos
codificados
Datos de
entrada
Figura 3-6. Esquema del Turbo Código de DVB-SH
Cada encoder se define tal y como podemos ver en la siguiente figura. Se trata de
encoders de 8 estados (al contrario que en DVB-RCS, no son codificadores circulares y será
necesario añadir una secuencia de terminación para llevar el codificador a un estado conocido.
Patricio López Capitulo 3. Turbo Códigos
Noviembre 2011
48
S1 S2 S3
Datos de
entrada
Terminación
del Trellis
Paridad
Sistemática
Figura 3-7. Esquema del codificador RSC del Turbo Código de DVB-SH
5.2. Turbo código de DVB-RCS
DVB-RCS [19] adoptó los turbo códigos convolucionales por ser altamente flexibles,
fácilmente adaptables a un rango amplio de diferentes tamaños de bloques de los datos, así
como su versatilidad para diferentes tasas de transmisión y code rates. De hecho en el
estándar se definen una vasta gama de code rates y tamaños de palabra.
Las aplicaciones de DVB-RCS implican la transmisión de datos utilizando diferentes
tamaños de bloque y coding rates, por eso se vio la necesidad de sustituir los esquemas
clásicos de un simple código convolucional seguido de un Reed Solomon. De la misma manera
se requiere una velocidad de transmisión de hasta 2 Mbps.
Como hemos explicado previamente, los turbo códigos M-arios, y en concreto por su
factibilidad computacional los duo binarios, son esquemas de gran eficiencia para la aplicación
de este tipo de decodificación iterativa.
En el caso de los códigos duo binarios, el desarrollo del algoritmo se realiza sobre una
constelación QPSK, recordemos que los códigos binarios simples se mapeaban sus métricas
como valores reales entre -1 y 1 BPSK, ahora en cambio debemos agrupar los bits de dos en
dos, por lo que dicha formulación es óptima para el caso que nos ocupa. También cabe
destacar la utilización de codificadores convolucionales CRSC (Circular Recursive Sistematic
Convolutional). En el caso del código seleccionado para DVB-RCS
S1 S2 S3
Pu
nctu
rin
g
Datos de
entradaDatos
codificados
Figura 3-8. Esquema del Turbo Código de DVB-RCS
Patricio López Capitulo 3. Turbo Códigos
Noviembre 2011
49
5.3. Comparativa
A continuación presentamos una tabla con una estimación de las prestaciones
ofrecidas por ambos estándares para un canal AWGN. En el caso de DVB-SH se ha escogido la
configuración TDM, ya que es la única aplicable en DVB-RCS así como una constelación QPSK,
aspecto en común de los dos estándares.
De las guías de implementación de DVB-SH [26] y DVB-RCS [27] podemos establecer
una clara comparativa de sus prestaciones.
Es importante apuntar que el Turbo Código de RCS se define de manera mucho más
flexibles, y en general trabaja con palabras de código bastante más pequeñas, lo que hace
disminuir sus prestaciones. Podemos ver como en la tasa de código 2/3, las prestaciones son
prácticamente iguales a pesar de tener una palabra de código más corta. Estos resultados se
han estimado para un Turbo Decoder con aproximación Max-Log-MAP y 6 iteraciones.
Tabla 3-2. Comparativa de prestaciones DVB-RCS y DVB-SH. TDM. Canal AWGN
DVB-SH DVB-RCS
Tamaño de palabra
12282 bits (8 paquetes MPEG)
1504 bits (1 paquete MPEG)
53 bytes 16 bytes
1/5 -3,9
2/9 -3,4
1/4 -2,8
2/7 -2,1
1/3 -1,2 1,9 2,2 3,2
2/5 -0,2 2,1 2,4 3,4
1/2 1,1 2,5 2,8 3,7
2/3 3,2 3,1 3,7 4,9
3/4 3,8 4,5 5,6
4/5 4,4 5,3
6/7 5,1 6,0
6. Conclusión
En este capítulo hemos descrito con profundidad el algoritmo MAP, utilizado para los
decodificadores RSC o CRSC que conforman el turbo decoder. Hemos presentado las
expresiones que definen el algoritmo y que serán objeto de análisis para presentar una
implementación paralela de un proceso fuertemente dependiente de resultados en instantes
anteriores.
No sólo nos ceñiremos a la aceleración de Turbo Códigos binarios, si no que
realizaremos un estudio general de los códigos m-arios, por ello hemos presentado también
sus características más importantes
Capítulo 4. Paralelización del Turbo Decoder. ACS y Sliding Window
1. INTRODUCCIÓN ..................................................................................................................... 51
2. TÉCNICAS RADIX PARA LA PARALELIZACIÓN DE LOS DECODIFICADORES SISO. ..................................... 51
2.1. Cuello de botella algoritmo de Viterbi ..................................................................... 51 2.1.1. Rápida descripción del algoritmo de Viterbi .................................................................... 52 2.1.2. Posibles optimizaciones del algoritmo de Viterbi ............................................................ 53
2.2. De la técnica de anticipación a las estructuras Radix-N .......................................... 55
3. ALGORITMO DE VENTANA DESLIZANTE (SLIDING WINDOW) .......................................................... 55
3.1. Prestaciones de Sliding Window .............................................................................. 58
3.2. Paralelización con Sliding Window .......................................................................... 59
4. CONCLUSIÓN ........................................................................................................................ 62
Patricio López Capitulo 4. Paralelización del Turbo Decoder.
ACS y Sliding Window
Noviembre 2011
51
1. Introducción
En este capítulo presentamos dos de los conceptos fundamentales que aplicamos para
la paralelización del Turbo Decoder y su posterior implementación sobre una tarjeta gráfica de
propósito general.
Inicialmente enfocamos nuestro estudio en paliar la latencia producida por los
procesos ACS [28] (Add, Compare, and Select) es decir, procesos que actualizan sus elementos
con datos de un estado anterior (Add), y posteriormente se selecciona alguno de ellos
siguiendo algún criterio (min, max,..). Esta operación de selección es especialmente costosa, ya
que en condiciones de no paralelización, la selección de un elemento dentro de una tabla de N
elementos conllevaría la ejecución de N-1 instrucciones. Estos procesos ACS están
omnipresentes en todo el proceso de decodificación de los Turbo Códigos y de hecho su
análisis se remonta a los códigos Viterbi [28] , donde ya encontrábamos este cuello de botella.
En segundo lugar estudiaremos técnicas propuestas para la paralelización del Turbo
Código [29] dividiendo la palabra de código y procesando la misma en sub-bloques.
Inicialmente, estas técnicas se proponen para el ahorro de memoria aunque de manera
inmediata, éste algoritmo, llama de ventana deslizante se aplica de forma inmediata para
paliar problemas de latencia, en las que encuadramos nuestro problema.
2. Técnicas Radix para la paralelización de los decodificadores
SISO.
En el proceso de decodificación de los decodificadores SISO que conforman el Turbo
Decoder encontramos en el proceso de cálculo de las Forward y Backward metrics un
procedimiento muy similar al efectuado en algoritmo de Viterbi para la determinación de la
secuencia transmitida más probable. De hecho, es el algoritmo de Viterbi el que motiva la
búsqueda de arquitecturas óptimas para el problema ACS, unidad básica que también está
presente en el cálculo de las A y B de los decodificadores SISO del Turbo Decoder.
2.1. Cuello de botella algoritmo de Viterbi
Los códigos convolucionales y el algoritmo de decodificación de Viterbi se utilizan
ampliamente en los sistemas de comunicación digital para alcanzar transmisiones robustas,
libres de errores. El algoritmo de Viterbi [20] es el algoritmo óptimo para la decodificación de
los códigos convolucionales, ya que nos da la solución ML. Éste está basado en el estudio de un
grafo ponderado cuyo fin es proporcionar una reconstrucción de la secuencia completa que
conformó la entrada del codificador convolucional basándose simplemente en la versión
recibida afectada por el canal y el ruido.
Como ya hemos comentado, con la evolución de las comunicaciones digitales se han
hecho necesarias nuevas técnicas de codificación, más robustas, con menor latencia en su
decodificación y con una proporción de overhead menor. Al algoritmo de Viterbi le ha ocurrido
Patricio López Capitulo 4. Paralelización del Turbo Decoder.
ACS y Sliding Window
Noviembre 2011
52
lo mismo, con el tiempo se ha exigido sobre él una mayor ganancia de código, lo que ha hecho
que se diseñen códigos sustancialmente más complejos
2.1.1. Rápida descripción del algoritmo de Viterbi
El algoritmo de Viterbi se puede ver simplemente como el cómputo del camino más
corto de un grafo formado por el trellis que define el codificador convolucional. El algoritmo
seguido para ello se puede definir en los siguientes pasos:
Cálculo de los pesos de las ramas del trellis. Llamadas métricas de las ramas
(branch metrics)
Cómputo recursivo de los caminos más cortos a cada estado del instante n,
actualizando desde el instante n-1. En este paso se realiza la selección actualizando
el camino “superviviente”. ¡Aquí nos encontramos con el proceso ACS!
Por último, se recorre hacia atrás el trellis completo obteniendo un único camino
desde el instante inicial hasta el final, el más corto, dándonos la solución óptima.
t1 2 3 4 5
Figura 4-1. Ejemplo de trellis binario con 4 estados
El procedimiento del ACS en el algoritmo de Viterbi se puede representar de la
siguiente forma, donde las métricas para el path (PM, Path Metrics) se calculan a partir de la
iteración anterior y de las métricas asociadas a las ramas (BM, Branch Metrics), por lo que para
el caso de un trellis binario (sólo dos ramas llegan y salen de cada estado)
Donde en la primera expresión y representan las métricas acumuladas y que
llegan al estado del instante siguiente , provenientes de los estados y
respectivamente. Y y representan las métricas asociadas a las ramas.
En la figura siguiente presentamos el bloque de la unidad ACS para un trellis binario.
Para que la secuencia de entrada pueda ser decodificada debemos recuperar el camino más
corto de cada paso realizado a lo largo del trellis. Tradicionalmente existen dos formas de
realizar la decodificación de Viterbi, aunque ambas tienen que lidiar con la actualización
recursiva y por lo tanto un throughput límite. Por un lado encontramos la basada en el
Patricio López Capitulo 4. Paralelización del Turbo Decoder.
ACS y Sliding Window
Noviembre 2011
53
intercambio de registros, apropiada para trellis sencillos y con unas posibilidades de
throughput bastante altas. Por otro lado, la técnica de Trace Back es más apropiada para trellis
más complejos por sus características de implementación con mejores prestaciones en área y
disipación de potencia.
Add SelectCompare
BMi,i+1
BMj,i+1
PMi
PMj
Decisión
PMi+1
Figura 4-2. Unidad básica de Add Compare and Select para una selección binaria
2.1.2. Posibles optimizaciones del algoritmo de Viterbi
Las implementaciones de baja latencia del algoritmo de Viterbi sólo se puede
conseguir acelerando el procesamiento de alguno o varios de los pasos anteriormente
comentados. Como la unidad de ACS es el punto de mayor complejidad, en él encontramos el
cuello de botella que limita nuestra tasa de transmisión. El problema se puede atacar con
alguna de las siguientes técnicas:
Transformaciones por anticipación (Look-Ahead)
Desenrollado de bucles
Retiming
Nos centraremos en la primera técnica ya que es la que permite ampliar nuestro
problema vectorialmente.
Consideremos el trellis representado en la Figura 4-1.. En cada intervalo de tiempo se
computan las métricas asociadas a cada rama y se escogerá entre el camino de menor peso
para actualizar el estado. Podemos ver que para los 4 saltos en la figura, tendremos que llevar
a cabo el proceso descrito.
En cambio, en la siguiente figura hemos realizado una transformación sobre el mismo
trellis de manera que podemos alcanzar directamente el cómputo de las métricas de estado en
saltándonos un instante de tiempo.
Patricio López Capitulo 4. Paralelización del Turbo Decoder.
ACS y Sliding Window
Noviembre 2011
54
1 3 5
Nueva escala de tiempo
1 2 3
Figura 4-3. Trellis comprimido
Desafortunadamente, al realizar esta transformación, el número de ramas que entran
y salen de cada estado ha aumentado a 4, por lo que crecerá el tamaño del comparador que
deberemos aplicar en nuestros procesos ACS, donde ahora tendrá que calcular un máximo de
4 valores posibles. Extrapolando este procedimiento podemos extender el trellis (o mejor
dicho comprimir) para “saltarnos” un número n de pasos.
En este caso, los valores de las métricas en los estados coincidirán con los del trellis
originario, obviamente sólo hemos calculado aquellos que no nos hemos “saltado”.
Se demuestra que las métricas o pesos asociados a las ramas en el nuevo trellis se
pueden obtener a partir de los pesos correspondientes al trellis original [30] de la siguiente
forma:
i
j
k
l
i+1
j+1
i+2
BMi,i+1 BMi+1,i+2
BMj,i+1
BMk,j+1
BMl,j+1
BMj+1,i+2
Figura 4-4. Branch metrics equivalentes
Patricio López Capitulo 4. Paralelización del Turbo Decoder.
ACS y Sliding Window
Noviembre 2011
55
Ya que para nuestro ejemplo, en el caso de m=2, es decir nos saltamos un paso de
cada 2, cada estado se puede alcanzar por los 4 posibles del instante anterior , , y (en la
nueva escala de tiempo, donde vamos de 2 en 2). Las nuevas métricas (ahora 4) asociadas a
cada rama equivalen a la suma.
2.2. De la técnica de anticipación a las estructuras Radix-N
Esta técnica de look-ahead no es más que una extensión de un problema de tipo Radix-
2, es decir, cada unidad ACS procesa y selecciona sobre dos entradas. Al comprimir el trellis,
esta unidad ACS se convierte en una unidad Radix-N, con N igual al número de ramas entrantes
en cada estado.
En el caso de nuestra extensión del trellis binario, obtendremos la serie Radix-4, Radix-
16, etc, ya que la complejidad de nuestro problema crece exponencialmente con base 2.
Ahora bien, la selección de un elemento de dicho conjunto creciente con el orden en
que comprimamos nuestro trellis, implicaría N-1 operaciones de selección en el caso de
realizar el proceso de forma secuencial. Por ello es de vital importancia desarrollar
arquitecturas de selección paralela que sean implementables en la unidad de procesamiento
gráfico (GPU).
En este punto hemos desarrollado el problema de la unidad ACS sobre los
decodificadores de Viterbi, ya que fue el detonante para las primeras evoluciones de dicho tipo
de arquitectura. Hemos de tener en cuenta que este problema se mapea de forma idéntica
sobre los procesos de cálculo de las métricas de un decodificador del tipo Log-MAP, por lo que
aprovecharemos dicha descripción para aplicarla al problema del cálculo de las forward y
backward metrics.
3. Algoritmo de Ventana Deslizante (Sliding Window)
Normalmente en los diseños de los Turbo Códigos de los últimos estándares de
sistemas comunicaciones se incluyen codificadores convolucionales en paralelo relativamente
sencillos, aunque en este tipo de concepciones normalmente también se incluyen interleavers
de gran tamaño que interconectan ambos codificadores. La complejidad y las prestaciones del
receptor en su conjunto vienen determinadas por la complejidad del turbo decoder. Aunque
las versiones de decodificadores en el dominio logarítmico del algoritmo MAP (Log-MAP)
consiguen un funcionamiento óptimo de este algoritmo SISO (Soft Input Soft Output), éste
requiere una gran cantidad de memoria para almacenar las diferentes variables necesarias
para el algoritmo. El tamaño de estas variables es proporcional a la longitud de la trama o de la
palabra de código.
Por lo que una de las mayores dificultades que presenta la implementación de los
turbo códigos son sus excesivos requisitos de memoria, ya que por ejemplo la palabra de
código con la que trabaja DVB-SH es de 12282 bits. Esto presenta un problema sobre todo para
el equipo portátil, donde el tamaño, las limitaciones de consumo y otros requisitos de
Patricio López Capitulo 4. Paralelización del Turbo Decoder.
ACS y Sliding Window
Noviembre 2011
56
portabilidad, no solamente limitan los recursos para el cómputo, sino también la memoria
disponible.
Por ello se presenta el método de la ventana deslizante, del inglés sliding window, con
lo que se trata de combatir los problemas de latencia y memoria en las técnicas de
decodificación de los turbo códigos. Esta técnica consiste básicamente en la división de la
palabra de código en segmentos que son procesados por el decodificador SISO de forma
independiente. Aunque esta reducción de latencia y memoria se alcanza pagando un precio en
las prestaciones de nuestro sistema. Para minimizar esta degradación de las prestaciones se
utiliza una ventana de guarda, es decir, no confinaremos el procesado y cálculo de las métricas
a cada segmento de la trama, sino que solaparemos su cálculo, es decir, comenzaremos el
cómputo de las métricas correspondientes a cada segmento algunos bits antes del comienzo
del segmento en cuestión. La longitud de esta ventana de guarda mejorará las prestaciones
proporcionalmente, pero tendremos que buscar una buena compensación entre la
penalización que sufrimos en cuestiones de latencia y la pérdida de prestaciones que
conseguimos paliar.
Los encoders que conforman el turbo coder comienzan en un estado conocido del
trellis para cada nuevo bloque. Para llevar el trellis en el instante final a un estado conocido
existen fundamentalmente un par de técnicas, la primera añade una pequeña cola al final de la
palabra para asegurar llevar el codificador a un estado conocido, esto lógicamente lleva a que
el tamaño del bloque varíe y que estas terminaciones no sean procesadas por el interleaver.
Una segunda opción consiste en encontrar un estado inicial dependiente de los datos de
manera que el estado inicial y final sean idénticos. A esto se le llama tailbitting y sobre ella nos
basaremos para desarrollar el concepto de sliding window.
Recordemos del capítulo anterior el proceso iterativo que lleva a cabo un turbo
decoder se basa en el intercambio de las métricas producidas por sus decodificadores SISO
hasta que se alcanza un grado de convergencia adecuado. De acuerdo con el algoritmo BCJR,
previamente explicado, las probabilidades producidas por los decodificadores se calculan de la
forma.
No olvidemos que todas estas métricas se corresponden con probabilidades en escala
logarítmica, lo cual nos ahorra, de partida realizar pesados productos, que elevarían de forma
importante la complejidad del proceso de decodificación.
La decodificación tradicional, secuencial, se realiza computando en primer lugar las
para el bloque completo (recorriéndolo hacia atrás) y almacenando su resultado, después se
calculan las y las métricas de salida (recorriendo la palabra de código hacia delante. En la
Figura 4-5 vemos una representación de este proceso. Donde podemos diferenciar (siempre de
forma secuencial), una etapa de carga en memoria, tras ella el cálculo de las backward metrics
Patricio López Capitulo 4. Paralelización del Turbo Decoder.
ACS y Sliding Window
Noviembre 2011
57
y por último, de forma simultánea el cálculo de las forward metrics junto con las métricas
finales de salida.
Carga de la información intrínseca (la que viene del canal) y de la información extrinseca proveniente del otro decoder
Cálculo y guardado de métricas B válidas
Cálculo de A y LLR de salida
N
0
t
Tiempo total de procesamiento
Ta
ma
ño
to
tal d
e la
pa
lab
ra d
e c
ód
igo
Figura 4-5. Proceso secuencial y sin sliding window
Cuando aplicamos el método de ventana deslizante (sliding window), el cálculo de las
métricas se inicia antes de cargar la palabra completa, es decir, no es necesario cargar en
memoria todo el bloque para comenzar los cálculos. Las pérdidas de prestaciones utilizando
esta técnica son despreciables si el tamaño de la ventana es lo suficientemente grande.
Carga de la información intrínseca (la que viene del canal) y de la información extrinseca proveniente del otro decoder
Cálculo y guardado de métricas B válidas
Cálculo de A y LLR de salida
Calculo de B “dummy”, no se guardan
Tiempo total de procesamiento
Ejecución sobre una ventanat
0
N
Ta
ma
ño
de
la
ve
nta
na
Figura 4-6. Proceso de decodificación con ventana deslizante (Sliding Window)
Patricio López Capitulo 4. Paralelización del Turbo Decoder.
ACS y Sliding Window
Noviembre 2011
58
En la siguiente figura podemos observar otra forma de representar dicho proceso
sobre la palabra de código. En él describimos los pasos para la ejecución del algoritmo y se ve
claramente el solapamiento provocado por la necesidad de una ventana de guarda para la
obtención de un estado inicial adecuado para las primeras métricas de cada ventana.
W W W
W+G
Palabra de código
1º - B 1ª ventana
2º - A 1ª ventana 3º - B 2ª ventana
4º - A 2ª ventana
B última ventana
A última ventana
Figura 4-7. Representación alternativa del proceso de ventana deslizante
3.1. Prestaciones de Sliding Window
Las prestaciones, mejor dicho, las pérdidas producidas por ésta técnica ya han sido
analizadas, por lo que nos atenemos a los resultados ya obtenidos. Se comprueba que la
degradación se hace mayor cuando trabajamos con palabras de código de mayor longitud,
aunque también este tipo de sistemas (con palabras de código grandes) ofrece grandes
mejoras utilizando alguna iteración más en el proceso de decodificación. Además, el algoritmo
analizado contempla la inclusión de un período de guarda, como ya hemos comentado antes,
para conseguir llegar a un valor de las métricas más aproximado al que se obtendría si
enventanado.
El efecto de Sliding Window se hace aún más patente cuando analizamos la tasa de
error de trama (FER, Frame Error Rate), ya que normalmente los sistemas con turbo códigos no
se diseñan con otro código corrector de errores concatenado.
Los resultados sobre los que nos apoyamos se han obtenido del turbo código del
estándar 3GPP [31] en su modo FDD, con una longitud de palabra de código de 5100 bits. Los
resultados obtenidos para una longitud de ventana de 100 bits [31] muestran que la mejora
producida en la FER al elevar el número de iteraciones es fuertemente dependiente con la
longitud del período de guarda que elijamos. Cuando el período de guarda es demasiado corto,
la pérdida de información no es despreciable y más iteraciones no consiguen compensar la
degradación. En cambio, cuando introducimos un período de guarda lo suficientemente
grande, en este caso se comprueba que 15 bits es adecuado (15 guarda / 100 ventana,
porcentaje razonablemente pequeño, que no incrementa demasiado las necesidades de
memoria), ya que las pérdidas introducidas por la utilización del algoritmo de sliding window
son prácticamente nulas, menores que 0,05 dB
Patricio López Capitulo 4. Paralelización del Turbo Decoder.
ACS y Sliding Window
Noviembre 2011
59
Tabla 4-1. Relación de pérdidas del algoritmo de ventana deslizante en función del período de guarda para el estándar 3GPP FDD.
Longitud período de guarda
Pérdidas respecto Max-Log-MAP sin Sliding Window (Para una BER de 10-4)
15 0,01 dB
10 0,02 dB
5 0,03 dB
3 0,05 dB aunque con mala convergencia
0 > 0,2 Mala convergencia suelo de error
Tabla 4-2. Influencia de la sobreiteración sobre el algoritmo de ventana deslizante
Longitud período de guarda
Iteraciones para BER= 10-4
Longitud período de guarda
Iteraciones para FER= 10-2
15 5 15 6
10 6 10 7
5 6 5 >>8
3 7 3 >>8
0 8 0 >>8
3.2. Paralelización con Sliding Window
Aplicando el concepto de Sliding window se puede implementar una arquitectura
paralela de decodificación. Se propone la utilización de tantos decodificadores SISO como
número de ventanas dividamos nuestra palabra de código. El algoritmo Sliding Window se
puede aplicar para decodificar varios subbloques simultáneamente sin apenas pérdidas de
prestaciones.
Inicialmente el algoritmo de ventana deslizante se ha concebido para conseguir
cumplir requisitos de memoria. En este caso, su utilización se enfoca en el cumplimiento de
requisitos de latencia. En la siguiente figura representamos el proceso clásico de ventana
deslizante, donde vamos adelantando el cálculo de las backward metrics en pequeñas
secciones, y por eso mismo necesitamos un período de guarda solamente para las en este
caso.
Patricio López Capitulo 4. Paralelización del Turbo Decoder.
ACS y Sliding Window
Noviembre 2011
60
Tiempo total de procesamiento
Ejecución sobre una ventanat
0
NT
am
añ
o d
e
la v
en
tan
a
Figura 4-8. Algoritmo de ventana deslizante sin paralelización
Donde combinando el enventanado con una redundancia hardware, en lo referente
decodificadores SISO, nuestro proceso de decodificación quedaría representado de la siguiente
manera, donde para segmento de entrada a cada uno de los decodificadores, es necesario
precargar también el final de la serie de datos de entrada para inicializar el cálculo de las
forward metrics.
Carga de la información intrínseca (la que viene del canal) y de la información extrinseca proveniente del otro decoder
Cálculo y guardado de métricas B válidas
Cálculo de A y LLR de salida
Calculo de B “dummy”, no se guardan
Calculo de A “dummy”, no se guardan
Patricio López Capitulo 4. Paralelización del Turbo Decoder.
ACS y Sliding Window
Noviembre 2011
61
Tiempo total de procesamiento
Ejecución sobre una ventanat
0
N
Ta
ma
ño
de
la v
en
tan
a
Ta
ma
ño
de
ca
da
su
bb
loq
ue
Figura 4-9. Algoritmo de ventana deslizante con paralelización.
El funcionamiento detallado es el siguiente:
Para cada sub-bloque (no lo queremos confundir con las ventanas, ya que implementaremos
una realización híbrida ventana deslizante – decodificación paralelo) se utilizan los últimos bits
de entrada del bloque anterior (n-1) para inicializar el cálculo de las A, de igual manera,
acudimos al principio del bloque siguiente (n+1) para inicializar el cálculo de las últimas B del
sub-bloque. De esta manera la latencia se reduce a la estrictamente necesaria para procesar
cada sub-bloque.
Patricio López Capitulo 4. Paralelización del Turbo Decoder.
ACS y Sliding Window
Noviembre 2011
62
Subbloque a procesar
Figura 4-10. Período de guarda tanto para las A como las B en los extremos de cada subbloque
De forma alternativa, también se puede realizar una codificación en sub-bloques, cada
uno con su correspondiente secuencia de terminación del proceso (tailbitting), con lo que de
esta manera nos ahorramos el intercambio de información (secuencias de inicialización) entre
los distintos decodificadores en paralelo.
En una posible arquitectura de decodificación paralelo, cada bloque de entrada se
dividirá en m sub-bloques, y cada sub-bloque se envía a un decodificador SISO diferente.
Donde en un punto de funcionamiento de régimen estacionario (no la primera iteración del
proceso de Turbo decodificación), primeramente se realiza la suma de las métricas (aportación
de la iteración previa). Después éstas son procesadas por cada decodificador SISO en paralelo y
sus resultados se envían a un interleaver paralelo donde se les aplica la correspondiente matriz
de permutación. Básicamente este interleaver paralelo consta de tantas matrices de
permutación como sub-bloques hayamos dividido la palabra, eso sí precisa de una unidad
extra de direccionamiento para gestionar la permutación global de la trama.
4. Conclusión
En este capítulo hemos sentado las bases para atacar por dos puntos de vista distintos
la paralelización del Turbo Decoder, tras la detección de dos de los puntos débiles en cuestión
de latencia, hemos estudiado las técnicas existentes y la posibilidad de su aplicación a la
estructura del Turbo Decoder para su posterior implementación sobre la unidad de
procesamiento gráfico (GPU).
La primera de las prácticas presentadas, la técnica Radix o de anticipación, no presenta
pérdida ninguna de prestaciones, eso sí, su aplicación implica un crecimiento de la complejidad
, en función de la compresión del trellis que realicemos, y por lo tanto una gran
demanda de capacidad computacional. Y en nuestro caso, si queremos aprovechar las
propiedades de esta transformación, computación paralela.
La segunda técnica, ventana deslizante paralelizada presenta ligeras pérdidas, aunque
como hemos visto, éstas son prácticamente nulas si escogemos bien el intervalo de guarda, es
decir, si es suficientemente largo como para llevar las métricas a un estado inicial factible.
Capítulo 5. Implementación del Turbo Decoder en la GPU
1. INTRODUCCIÓN ..................................................................................................................... 64
2. TURBO DECODER M-ARIO ....................................................................................................... 64
3. PARALELIZACIÓN SIN PÉRDIDAS ................................................................................................ 66
3.1. Paralelización del cálculo de las branch metrics ...................................................... 66 3.1.1. Limitaciones GPU ............................................................................................................. 69
3.2. Cómputo de las A, B y LLR de salida en la GPU ........................................................ 69 3.2.1. Limitaciones GPU ............................................................................................................. 74
4. SLIDING WINDOW ................................................................................................................. 74
5. CONCLUSIÓN ........................................................................................................................ 76
Patricio López Capitulo 5. Implementación del Turbo Decoder en
la GPU
Noviembre 2011
64
1. Introducción
En los capítulos anteriores hemos explicado los fundamentos de los algoritmos de
decodificación de los Turbo Códigos, así como sus puntos críticos y distintos métodos para
poder atajarlos. Previamente, también hemos introducido la herramienta CUDA, la cual
utilizaremos para implementar el algoritmo de turbo decodificación, en concreto nos
centraremos en la implementación de los decodificadores SISO que lo componen. A lo largo
del capítulo siguiente explicaremos cómo implementarlo utilizando CUDA y explicaremos
distintas aproximaciones o más bien pasos naturales a seguir para resolver el problema.
2. Turbo decoder M-ario
En distintas publicaciones se trata el cuello de botella que se produce en los elementos
Add, Compare and Select inherentes al algoritmo de Viterbi [28] [32] . En el caso del algoritmo
MAP, utilizado en los decodificadores que conforman el Turbo Decoder, encontramos procesos
del mismo estilo que el Viterbi, específicamente en el cómputo de las backward y forward
metrics (Eq. 1), por lo tanto proponemos las aplicación de estas técnicas de reducción para
paralelizar las diferentes etapas del proceso de decodificación SISO, pero también al mismo
tiempo obtener una versión m-aria de cualquier turbo código dado.
Eq. 1
Esta reducción se basa principalmente en métodos Radix, simplemente para acelerar el
tiempo de procesamiento del algoritmo de VIterbi. En este caso, la estrategia recibe el nombre
de m-step trellis. Ésta establece una compresión del trellis en el dominio temporal, en la cual
descansa el proceso de decodificación, pero también resulta en un crecimiento exponencial de
la complejidad (2n).
De esta manera, las métricas asociadas a las ramas del trellis comprimido, o de la
también llamada extensión M-aria, se pueden obtener de la suma de las tres componentes
principales que conforman las métricas del trellis binario. La nueva información extrínseca y los
términos asociados la parte de paridad y sistemática se obtienen respectivamente de la suma
de cada una de estas partes del trellis original. Esta suma de tres términos y la concatenación
del trellis se describe de manera sencilla en la siguiente expresión para las métricas de rama
resultantes, donde por simplicidad no representamos el índice temporal pero sí el orden del
nuevo trellis N.
Eq. 2
En la Figura 5-1 hemos representado la concatenación de dos pasos de un trellis
binario, resultando así en el trellis representado en la Figura 5-2. Como se expresa en la
Patricio López Capitulo 5. Implementación del Turbo Decoder en
la GPU
Noviembre 2011
65
ecuación anterior, cada término se deriva de la suma de los términos independientes asociados
al trellis binario.
),( 1
0
ll SS
),( 1
1
ll SS
1k k
1l l 1l
),( 1
0
ll SS
),( 1
1
ll SSS
1
S8
Figura 5-1. Encadenamiento de dos trellis binarios. Trellis correspondiente a DVB-SH
Como resultado de esta compresión y el consecuente aumento del orden del decoder
(número de bits tomados como entrada en cada instante de tiempo), el número de ramas que
desemboca en cada estado se incrementa exponencialmente y por lo tanto la función de
selección del máximo (proceso ACS), necesaria para llevar a cabo el cálculo de las métricas
forward y backward. Para aprovechar las ventajas que proporciona esta reducción Radix, es
fundamental asociar esta extensión del trellis con un diseño orientado a hardware, o al menos
disponer de capacidades de procesamiento especiales como lo son las provistas por las GPU.
1
N
2
N
3
N
1k k
S1
S8
Figura 5-2. Trellis duo binario, correspondiente a la extensión del trellis de DVB-SH
Patricio López Capitulo 5. Implementación del Turbo Decoder en
la GPU
Noviembre 2011
66
Tabla 5-1. Complejidad del Turbo Decoder M-ario.
Orden Número de métricas a calcular
Longitud de la palabra de código
1 196560 12285
2 196576 6143
3 262144 4096
4 786432 3072
5 629248 2458
6 1049088 2049
7 1798144 1756
3. Paralelización sin pérdidas
En primer lugar presentamos dos formas de acelerar la ejecución del Turbo Decoder
aplicando una paralelización con pérdidas nulas.
Atacaremos este problema a través de dos aproximaciones. Una primera en la que
simplemente paralelizamos el cálculo de las branch metrics, dejando para la CPU el resto de los
cálculos inherentes al algoritmo BCJR. Y una segunda aproximación, en la que presentamos un
modelo viable para su completa ejecución dentro de la GPU.
3.1. Paralelización del cálculo de las branch metrics
Como hemos comentado previamente, para el cómputo de las branch metrics
necesitaremos la información soft de entrada al decoder, la información a priori (obtenida de
la información extrínseca del otro decoder BCJR) y la estructura del trellis, ya que
necesitaremos conocer las entradas y salidas asociadas a cada transición que pueda darse en el
codificador RSC.
Donde hemos definido como las branch metrics para un trellis M-ario. En la
Figura 5-2 podemos ver un ejemplo de un turbo código duo-binario. Es importante remarcar
que el número de ramas que llegan a un estado específico ( ) se incrementa
exponencialmente con el número de bits asociado a cada transición (M):
Eq. 3
Por lo que el número total de branch metrics por palabra de código ( ) será
función de la longitud de la palabra , del número de estados que conformen el
trellis ( ) y del número de ramas por estado ( ):
Eq. 4
Patricio López Capitulo 5. Implementación del Turbo Decoder en
la GPU
Noviembre 2011
67
Como mostramos en la Figura 5-3, para la paralelización del cálculo de las branch
metrics, utilizaremos un grid bidimensional (como ya hemos visto previamente es la forma de
mapear un algoritmo en la GPU mediante CUDA), donde el procesamiento se distribuye sobre
filas y columnas. El número de columnas (es decir el número de thread blocks que
conforman una fila del grid), dependerá de la longitud de la palabra de código y del número
asignado de threads por bloque :
Eq. 5
En la Figura 5-3 representamos dos niveles de la jerarquía de la memoria de la GPU. La
memoria global contendrá los vectores donde almacenaremos las branch metrics, éstas serán
la salida del proceso que ejecutamos en la GPU y que transferiremos a la CPU. La información
necesaria para describir el trellis (entradas, salidas y correspondientes transiciones), la
información a priori y los datos de entrada se cargarán en la memoria compartida de cada
bloque (thread block), haciendo posible un acceso más rápido a la memoria y reduciendo así el
tiempo de ejecución.
Estado 1
Estado 8
Longitud efectiva de los datos
Memoria
Global
256 threads
por bloque
Branch
metrics
- Metrics for
backward
recursion
-Metrics for
forward
recursion
Memoria compartida
Información del Trellis
Información A Priori
Datos de entrada
Figura 5-3. Arquitectura jerarquizada y distribución del grid para el cálculo de las branch metrics.
Para ilustrar mejor el trabajo realizado hemos querido presentar un extracto del
código para el cálculo de las branch metrics, donde nos gustaría destacar los dos índices que se
definen inicialmente, idxAlpha y idxState, y que representarán la ubicación de cada thread
dentro del grid que hemos definido. Posteriormente, también destacamos las variables locales
Patricio López Capitulo 5. Implementación del Turbo Decoder en
la GPU
Noviembre 2011
68
en las que guardaremos resultados intermedios para el cálculo realizado por cada thread como
pueden ser la parte correspondiente a la parte sistemática, a priori o de paridad.
Posteriormente se ejecuta el código para cada hilo donde nos gustaría también
destacar la limitación para el número de hilos incluso en el caso (es lo normal) que el número
de hilos no complete de forma exacta los bloques asignados para este menester.
__global__ void gammaComputationCuda(float *PDData, float *DLAPriori,float
*PDGammaForward,int *PINextOut, int *PILastOut, int INumSteps, int
INumBranches, float Infin_gamma,int DataLength, int INumStates)
{
int idxAlpha = blockIdx.x*blockDim.x + threadIdx.x + 1;
int idxState = blockIdx.y;
/* ... */
float pdSystPart0[7];
float pdPriorPart0[7];
float pdSystPart1[7];
float pdPriorPart1[7];
/* ... */
float dGamma_ext, dGamma_extB;
/* ... */
betaLen = DataLength;
if ((idxAlpha > DataLength) || (idxState >= INumStates)) return;
/* ... */
for (k = 0; k<INumBranches; k++)
{
/* ... */
for(p=0; p<INumSteps; p++)
{
/* Cómputo parte a priori y sistemática */
}
for (p = 0; p < INumSteps; p++)
{
/* Cómputo parte de paridad */
}
dGamma_ext = dSystPart + dParityPart + dPriorPart;
/* Saturación */
PDGammaForward[/* .f(idxAlpha).. */] = dGamma_ext;
}
}
Figura 5-4. Cálculo de las branch metrics en la GPU. Extracto de código
Patricio López Capitulo 5. Implementación del Turbo Decoder en
la GPU
Noviembre 2011
69
En la Figura 5-5 presentamos un esquema donde se pueden ver las diferentes etapas
del algoritmo ejecutadas en la GPU y en la CPU respectivamente. Donde la transferencia de las
branch metrics desde la memoria global de la GPU hasta la memoria de la CPU ha de ser tenida
en cuenta como una etapa crítica en esta implementación.
K..1 An Bn
Alta paralelización
En CPU
Inp
ut D
ata
1..M
A P
rio
ri In
fo 1
..N
Tre
llis In
fo
An
-1
Bn
+1
A 1..N
B 1..N
1..K
LLR
GPU CPU
LLR 1..N1..K
Figura 5-5. Esquema de ejecución de la 1ª aproximación. Branch metrics en la GPU
3.1.1. Limitaciones GPU
La gran limitación, o al menos un factor a tener en cuenta en la implementación de
dicho algoritmo es la transferencia de las branch metrics desde la GPU a la CPU ya que el ancho
de banda del bus de datos PCI, por el que se comunican CPU y GPU es bastante limitado en
comparación con los accesos a memoria que se realizan dentro de la GPU. Sobre todo
teniendo en cuenta la gran cantidad de datos que hemos devolver si aplicamos dicha
aproximación.
3.2. Cómputo de las A, B y LLR de salida en la GPU
Como segunda aproximación para la paralelización del decoder, presentaremos una
arquitectura diseñada para su completa ejecución en la GPU. Esta función de decodificación
proporciona las LLR finales asociadas a cada bit (para cada iteración). Las métricas LLR se
transfieren de la memoria global de la GPU a la memoria de la CPU, donde opuestamente a la
primera aproximación, trataremos siempre con una cantidad constante e independiente del
orden del Turbo Código.
En este caso, el cómputo de las forward y las backward metrics se lleva a cabo en la
GPU. Como podemos ver directamente en la Figura 5-5, la densidad de paralelización en estas
etapas no es demasiado intensa (cálculo de las A y las B), ya que sólo se pueden realizar
cálculos simultáneos para cada instante de tiempo debido a la dependencia entre instantes de
tiempo consecutivos.
Patricio López Capitulo 5. Implementación del Turbo Decoder en
la GPU
Noviembre 2011
70
Como ya hemos señalado, el número de ramas sufre un incremento exponencial con el
aumento del orden del Turbo Código, por lo que para el cálculo de las A y B deberemos
implementar una función óptima para el cálculo del máximo ya que el conjunto de elementos
(ramas) podrá ser mucho mayor que para el caso binario (donde sólo teníamos dos elementos
de entrada en la función max).
Para eso hemos implementado kernels que proporcionan 8 máximos en paralelo (ya
que hemos particularizado el estudio para el TC de DVB-SH, y éste sólo tiene 8 estados) para
los 8 conjuntos de ramas de cada estado.
En el caso de no haber dispuesto de una arquitectura especial que permitiese la
paralelización, el cómputo secuencial del máximo se habría convertido en una actividad
demasiado pesada, sobre todo para los trellis de un orden alto.
En nuestro caso, si seguimos la arquitectura representada en la Figura 5-6 y calculamos
un máximo por cada thread block, el número de ramas que llegan a cada estado no podrá
exceder el número de threads asignados a cada thread block.
Cálculo de las A
Estado 8Estado 1
Ram
as
Max 8Max 2Max 1
Figura 5-6. Arquitectura CUDA para el cálculo de 8 máximos simultáneos
De esta manera optimizaremos el cómputo del máximo. Donde su cálculo secuencial
hubiese requerido pasos, nosotros obtendremos el mismo resultado en pasos
simplemente ejecutando dicha función en paralelo. De esta manera paliaremos el crecimiento
exponencial de la complejidad de la función del máximo. La aceleración óptima la
obtendremos para el caso de orden 5 (32 ramas), pues el cálculo del máximo tiene lugar
exclusivamente dentro de cada warp (32 threads) y no precisa de instrucciones de
sincronización al ejecutarse puramente como un SIMD. En la figura 6 mostramos la
arquitectura CUDA para este proceso. El número de bloques se ha adaptado al trellis, de
manera que dispondremos de tantos bloques como estados. En nuestro caso estamos
tomando como base el Turbo Código de DVB-SH, por lo que tendremos 8 estados.
Patricio López Capitulo 5. Implementación del Turbo Decoder en
la GPU
Noviembre 2011
71
A1 A2 A3 A16 A17 A18 A32
MAX MAX
MAX
MAX
MAX
)32(log2
Figura 5-7. Paralelización del cálculo del máximo
También hemos de señalar que en los dispositivos CUDA con capacidad 2.0, o lo que es
lo mismo, aquellos que disponen de la arquitectura Fermi, los accesos a memoria se agrupan
en conjuntos de 128 bytes, y un warp completo puede leer/escribir de la memoria en un único
acceso, siempre claro que todos los threads del warp accedan al mismo segmento de 128
bytes (un elemento en flotante ocupa 4 bytes).
Desde el punto de vista de la memoria global, el tiempo óptimo de procesamiento
para las backward y forward metrics se obtiene en los Turbo Códigos de orden 1 y 2, ya que los
accesos para los 8 estados se procesan en paralelo (en el caso de que tengamos un trellis de 8
estados) y para cada bloque se realiza una única transferencia de memoria. En el caso de un TC
de orden 3 se requerirán dos accesos (ya que necesitamos dos segmentos de 128 bytes). Para
obtener un tiempo de ejecución óptimo será necesaria la desactivación de la cache L1 de la
arquitectura Fermi, ya que ralentiza los accesos a memoria en el caso de que estos no estén
bien agrupados dentro de un segmento.
También hemos querido mostrar un extracto de código correspondiente al cálculo del
máximo con el fin de proporcionar una mejor visión de la solución al problema. Cabe destacar
la ausencia de sincronización entre los threads pertenecientes a un mismo warp.
En la siguiente muestra de código también podemos observar la realización del cálculo
de la corrección (max*).
También destacamos el uso de la variable del tipo volatile para asegurar la copia del
dato en un registro, ya que para la arquitectura Fermi, en estos casos el compilador podría
enmascarar la utilización de dicha variable al hacer uso de su profunda jerarquización de la
memoria cache.
Patricio López Capitulo 5. Implementación del Turbo Decoder en
la GPU
Noviembre 2011
72
Figura 5-8. Extracto de código para el cálculo del máximo. Sin sincronización dentro del warp
Con el fin de agilizar el proceso de transferencia de memoria, sobre todo de las branch
metrics, la memoria reservada para éstas es del tipo page-locked, es decir memoria virtual
asociada al dispositivo gráfico.
unsigned int i = stateBlock*blockDim.x + threadIdx.x;
/* ... */
threadSum[tid] = in[i];
__syncthreads();
if(tid < 64 && n>=128) threadSum[tid] = fmaxf(threadSum[tid+64],threadSum[tid]);
__syncthreads();
if(tid < 32 && n>=64) threadSum[tid] = fmaxf(threadSum[tid+32],threadSum[tid]);
__syncthreads();
volatile float *smem = threadSum;
if((tid < 16) && n >= 32) smem[tid] = fmaxf(smem[tid + 16], smem[tid]);
if((tid < 8) && n >= 16) smem[tid] = fmaxf(smem[tid + 8], smem[tid]);
if((tid < 4) && n >= 8) smem[tid] = fmaxf(smem[tid + 4], smem[tid]);
if((tid < 2) && n >= 4 ) smem[tid] = fmaxf(smem[tid + 2], smem[tid]);
if((tid < 1) && n >= 2 ) smem[tid] = fmaxf(smem[tid + 1], smem[tid]);
inc[tid] = __expf(in[i] - threadSum[0]);
__syncthreads();
if(tid < 64 && n>=128) inc[tid] += inc[tid + 64];
__syncthreads();
if(tid < 32 && n>=64) inc[tid] += inc[tid + 32];
__syncthreads();
volatile float *smem1 = inc;
if((tid < 16) && n >= 32 ) smem1[tid] += smem1[tid + 16];
if((tid < 8) && n >= 16 ) smem1[tid] += smem1[tid + 8];
if((tid < 4) && n >= 8 ) smem1[tid] += smem1[tid + 4];
if((tid < 2) && n >= 4 ) smem1[tid] += smem1[tid + 2];
if((tid < 1) && n >= 2 ) smem1[tid] += smem1[tid + 1];
if(tid == 0)
dCorrection[0] = threadSum[0] + __logf(inc[0]);
/* ... */
Patricio López Capitulo 5. Implementación del Turbo Decoder en
la GPU
Noviembre 2011
73
K..1 An Bn
Alta paralelización
Paralelización de los procesos ACSIn
pu
t D
ata
1..M
A P
rio
ri In
fo 1
..N
Tre
llis In
fon
An
-1
Bn
+1
A 1..N
B 1..N
1..K
LLR
GPU CPU
LLR 1..N
Figura 5-9. Esquema de ejecución de la 2ª aproximación. Todo el decoder en la GPU
A continuación añadimos el extracto de código correspondiente a las fases
fundamentales de la decodificación SISO, donde vemos inicialmente el cálculo de las branch
metrics, donde la función gamma_ext llamará internamente a su propio kernel.
Posteriormente se realiza el cálculo de las A y B, donde podemos ver el bucle para el
índice temporal (no paralelizable). El cálculo de éstas se ha dividido en una actualización de las
métricas y un posterior cálculo del máximo.
Y por último de forma totalmente paralela se realiza el cálculo de los LLR de salida.
/* ... */
gamma_ext( PINextOutBinExt, PILastOutBinExt , pdData_gpu, pdLAPriori_gpu
,INumSteps,INumBranches, infin_gamma, alphaLen, pdGammaForward_gpu,
pdGammaBackwards_gpu);
/* ... */
for (indexAlpha=1; indexAlpha<alphaLen; indexAlpha++)
{
indexBeta = betaLen - indexAlpha - 1;
ABCuda<<<dimGridAB , dimBlockAB>>>(alphaLen, INumStates,
INumBranches, pdAlpha_gpu, /* ... */);
maxABCuda<<<dimGridMaxAB, dimBlockMaxAB>>>(INumBranches,
dExtAuxA_gpu, /* ... */);
}
/* ... */
llrCuda<<<dimGridLLR ,dimBlockLLR >>>( INumBranches, INumStates, INumSteps,
pdAlpha_gpu, pdBeta_gpu, pdGammaForward_gpu, /* ... */, pdLogLR_gpu, /*
... */
);
Figura 5-10. Decodificación completa en la GPU. Extracto de código
Patricio López Capitulo 5. Implementación del Turbo Decoder en
la GPU
Noviembre 2011
74
3.2.1. Limitaciones GPU
Resumiendo los aspectos limitantes más importantes de esta implementación, destacamos el
direccionamiento lejos de ser contiguo de los accesos en lectura y escritura a las métricas
asociadas a cada transición, ya que la naturaleza del trellis se aleja bastante de la idealidad
para la optimización de los accesos a memoria.
La arquitectura utilizada para el cálculo de los máximos también nos establece otra
limitación en lo referente al máximo orden de Turbo Código que simularemos. Ya que el
número óptimo de hilos para un máximo aprovechamiento de la gráfica suele tomar valores de
128, 256 y como máximo 1024 para la arquitectura Fermi. En nuestro caso hemos tomado 128
hilos por bloque, lo que limitará nuestro orden mayor a 7.
No como limitación, pero sí como factor a tener en cuenta para el diseño (ya
comentado en el capítulo previo dedicado a CUDA), tenemos que contemplar el uso de las
variables del tipo volatile cuando trabajamos con la arquitectura Fermi.
4. Sliding Window
En las dos secciones anteriores, hemos presentado una paralelización básica sin
ninguna pérdida. En este punto, tomaremos el Sliding-Window como base de manera que
podamos explotar toda la capacidad de la GPU. El Siliding Window ha sido históricamente
aplicado para dar viabilidad al turbo código en condiciones de memoria limitada así como para
satisfacer requisitos de throughput. En nuestro caso, aplicaremos dicho algoritmo para el
procesamiento paralelo de la palabra. Esta aproximación se basa en dividir la palabra de
código en varias ventanas. Como ya hemos explicado en capítulos anteriores, un aspecto
esencial para conservar unas prestaciones dentro de un límite aceptable es la utilización de
secciones de entrenamiento que ayuden al decoder a alcanzar un estado favorable para el
proceso de decodificación.
Estas secciones de entrenamiento, también llamadas períodos de guarda, son
necesarias tanto para el proceso de cálculo de las forward tanto de las backward metrics. A
continuación recordamos el procedimiento clásico de aplicación de dicho algoritmo, tal y como
mostramos en secciones anteriores. En primer lugar se calculaban las B correspondientes a
una ventana, y posteriormente las A junto con las LLR finales.
Patricio López Capitulo 5. Implementación del Turbo Decoder en
la GPU
Noviembre 2011
75
W W W
W+G
Palabra de código
1º - B 1ª ventana
2º - A 1ª ventana 3º - B 2ª ventana
4º - A 2ª ventana
B última ventana
A última ventana
Figura 5-11. Algoritmo Sliding Window
Como también hemos explicado en capítulos previos, una correcta elección del
tamaño de la ventana y sobre todo del período de guarda establecerán las pérdidas dentro de
unas cotas bastante razonables
Utilizando la misma representación que en [32] , el proceso de decodificación queda
representado en la Figura 5-12, de forma que nos podemos hacer una idea clara del orden de
procesamiento y del tiempo de ejecución de cada una de las etapas (A, B y LLR).
Primeramente, mostramos un diagrama temporal el cual representa la paralelización de las
backward y forward metrics. Podemos diferenciar las distintas ventanas cuyas métricas se
calculan simultáneamente y los períodos de entrenamiento (o de guarda) necesarios para cada
ventana, de forma que se alcanza un estado válido para el proceso de decodificación.
Finalmente todas las métricas LLR se calculan en paralelo (ya que aquí podemos paralelizar
sobre la variable tiempo sin ningún problema de dependencias).
Patricio López Capitulo 5. Implementación del Turbo Decoder en
la GPU
Noviembre 2011
76
W1
W2
WN
Fo
rwa
rd m
etr
ics
Ba
ckw
ard
me
tric
s
Training for backward recursion
Training for forward recursion
Nb
8 blocks
Forward metrics
8 blocks
Backward metrics
Nu
mb
er o
f
win
do
ws
t
Pa
ralle
l L
LR
co
mp
uta
tio
n
Backward metrics computation
Forward metrics computation
Code word length
W
2W
max 1 max 8 max 1 max 8
0
Figura 5-12. Esquema de la arquitectura con aplicación del algoritmo Sliding Window.
5. Conclusión
En este capítulo hemos realizado una explicación exhaustiva del procedimiento a
seguir para la implementación del algoritmo de decodificación SISO en la GPU. Lo que
posteriormente nos permitirá obtener resultados y evaluar las prestaciones en tiempo de
ejecución de las mismas.
Obviamente el Turbo Decoder no sólo está formado por los decodificadores sino
también por los interleavers, en el ámbito de este trabajo no hemos visto oportuno entrar en
su estudio y lo apuntamos para posteriores proyectos.
Capítulo 6. Resultados de la Implementación en CUDA del Turbo Decoder
1. INTRODUCCIÓN ..................................................................................................................... 78
2. RESULTADOS EXPERIMENTALES ................................................................................................ 78
3. RESULTADOS SIN PÉRDIDAS ..................................................................................................... 79
4. SLIDING WINDOW ................................................................................................................. 83
5. CONCLUSIÓN ........................................................................................................................ 84
Patricio López Capitulo 6. Resultados de la impementación CUDA
del Turbo Decoder
Noviembre 2011
78
1. Introducción
En este capítulo mostraremos los resultados obtenidos para las diferentes
implementaciones propuestas para el Turbo Decoder paralelo a lo largo de este trabajo.
Primeramente introduciremos aquellos resultados que no presentan ninguna pérdida,
y posteriormente mostraremos las prestaciones de la implementación paralelo con pérdidas.
De cualquier forma, todos nuestros resultados tratan sobre el tiempo de ejecución, y no
presentamos resultado alguno de pérdidas, ya que para dicha implementación, como ya se ha
comentado en capítulos anteriores, éstas están perfectamente acotadas y estudiadas bajo la
elección de los parámetros adecuados.
2. Resultados experimentales
Hemos llevado a cabo diferentes simulaciones tomando como algoritmo bajo prueba
el Turbo Código seleccionado para los dispositivos DVB-SH [8]. Este Turbo Código está
conformado por dos codificadores RSC (Recursive Systematic Convolutional) de 8 estados y una
palabra de código de 12282 bits más otros 3 de cola (tail bits).
Para simular los Turbo Códigos M-arios y obtener conclusiones adecuadas sobre su
complejidad, hemos extendido el trellis binario del codificador de DVB-SH a un trellis M-ario
[17] aplicando las técnicas m-step. De esta manera los Turbo Códigos no binarios simulados en
este trabajo son versiones diferentes de un mismo turbo código, lo que nos permite una
comparación en condiciones óptimas entre los Turbo Códigos con un trellis de orden diferente.
Las simulaciones en la GPU se han realizado sobre una tarjeta NVIDIA GTX 470 (1.2
GHz) con 448 núcleos CUDA (recordar que 32 núcleos CUDA conforman un multiprocesador), y
una memoria de 1.2 GB con un ancho de banda de 133.9 GB/s. Todo ello sobre un procesador
Intel i7 a 2.8 GHz y 6GB de memoria RAM.
Con el fin de proporcionar una visión general de las simulaciones y de los mejores
resultados obtenidos, en la Tabla 6-1 resumimos los aspectos más importantes. Para cada
implementación los resultados representan la ejecución de un total de 50 iteraciones,
equivalente a la ejecución de 100 decodificadores SISO.
Por supuesto, detallaremos todos los resultados obtenidos en los siguientes puntos,
pero observando la Tabla 6-1, podemos ver que la utilización de la GPU para la ejecución del
Turbo Decoder nos proporciona de base unas prestaciones algo mejores que la ejecución del
código aprovechando los 4 núcleos reales de los que dispone el procesador i7. Esta aceleración
se hace increíblemente mayor cuando paralelizamos totalmente el proceso de decodificación y
aplicamos la técnica de Sliding Window.
Patricio López Capitulo 6. Resultados de la impementación CUDA
del Turbo Decoder
Noviembre 2011
79
Tabla 6-1. Resumen de las simulaciones en los bancos de prueba utilizados para las simulaciones
Arquitectura
CPU CUDA
Intel i7 2.8 GHz 6 GB RAM
NVIDIA GTX 470 (1.2 GHz) 448 CUDA cores
1 core 4 cores Branch metrics
Branch metrics + AB + LLR
Sliding window
Mejores resultados (s)
16,25 4,43 3,12 3,45 0,82
3. Resultados sin pérdidas
En la Tabla 6-1 presentamos los resultados para la implementación sin pérdidas. Con el
objetivo de trasladar una idea de la densidad de computación, en las primeras dos columnas
hemos incluido el número total de branch metrics y la longitud de la palabra respectivamente.
Las tres columnas siguientes muestran el tiempo de ejecución para las 7 implementaciones
diferentes, en lo que se refiere al orden del Turbo Código. Dentro de estos resultados hemos
incluido primeramente la implementación sobre la CPU, seguidamente presentamos los
resultados para la ejecución completa del Turbo Decoder sobre la GPU y por último incluimos
la ejecución mixta GPU/CPU (donde sólo las branch metrics se computan sobre la tarjeta
gráfica). La última columna presenta la aceleración máxima para cada caso, donde el resultado
más favorable en la ejecución sobre la CPU (es decir las peores condiciones de ganancia) ha
sido tomado como referencia para cada caso.
De cualquier manera, tomando el Turbo Código de orden 1 como el caso más favorable
para la implementación completa en la CPU y el mejor caso dentro de las dos
implementaciones en las que entra en juego la GPU, esto es el de orden 2 para la
implementación mixta, alcanzamos una aceleración de más de 5 veces. Es importante observar
que la mínima aceleración se obtiene para el orden 4, donde existe un punto de inflexión y la
necesidad de ejecutar las A y B en la GPU se hace notable.
Patricio López Capitulo 6. Resultados de la impementación CUDA
del Turbo Decoder
Noviembre 2011
80
Tabla 6-2. Resultados de tiempo de ejecución para la implementación sin pérdidas
M CPU GPU
(s) CPU/ GPU
Max Speed-up 1 core 4 cores
1 196560 12285 16,25 4,43 16,86 3,48 4,7
2 196576 6143 16,62 4,44 8,52 3,12 5,2
3 262144 4096 19,97 5,29 5,76 3,79 4.3
4 786432 3072 26,61 7,05 4,4 5,22 3.7
5 629248 2458 39,74 10,44 3,76 8,14 4.3
6 1049088 2049 64,55 16,85 3,47 13,46 4.7
7 1798144 1756 113,28 29,49 3,63 23,26 4,5
El cómputo de las branch metrics debe ser subrayado como un aspecto clave dentro de
la aceleración del Turbo Decoder. En la Tabla 6-3 se muestra el tiempo empleado para el
cálculo de las branch metrics para una única ejecución. Representamos respectivamente el
tiempo de ejecución para la CPU y para la GPU. Esta etapa del proceso de decodificación es una
de las más intensas en términos de densidad de cálculos sufriendo de esta manera la
aceleración más drástica al ser ejecutadas sobre la GPU. Hemos de destacar también el tiempo
empleado para la devolución de las métricas, es decir la carga desde la memoria de la GPU a la
memoria de la CPU (esto claro sólo en la implementación mixta GPU/CPU).
Tabla 6-3. Tiempos de ejecución y carga para el cálculo de las branch metrics
M CPU (ms)
GPU (ms)
Speed-up BM load
(ms)
1 196560 2 (BPSK) 53 0,1 530 0,7
2 196576 4 (QPSK) 57 0,2 285 0,7
3 262144 8 (8PSK) 60 0,3 200 0,8
4 786432 16 65 0,6 108 1,0
5 629248 32 81 1,6 51 1,6
6 1049088 64 109 3,8 29 2,7
7 1798144 128 160 7,6 21 4,5
Patricio López Capitulo 6. Resultados de la impementación CUDA
del Turbo Decoder
Noviembre 2011
81
En la Figura 6-1 y en la Figura 6-2 se representa la descomposición de las diferentes
etapas presentes en el cómputo de las branch metrics. En la Figura 6-1, se representa el
comportamiento de la arquitectura mixta (CPU/GPU) donde se puede ver el crecimiento del
tiempo dedicado a la transferencia de los datos. Vemos cómo la carga de la información
necesaria desde la CPU a la GPU se conserva constante mientras que la transferencia de las
métricas resultantes crece considerablemente con el orden del Turbo Código. La carga en
memoria se estudia como un aspecto importante ya que constituye una proporción nada
despreciable del procesamiento en esta etapa.
Figura 6-1. Cálculo de las Branch Metrics. Resto del decoder en la CPU
Figura 6-2. Cálculo de las Branch Metrics. Todo el decoder en la GPU
Por último, para resumir los resultados obtenidos, presentamos en una misma gráfica
todos los datos conjuntos sobre tiempo de ejecución, donde vemos claramente el punto del
Patricio López Capitulo 6. Resultados de la impementación CUDA
del Turbo Decoder
Noviembre 2011
82
turbo decoder de orden 4 como el punto de inflexión para la selección de una aproximación u
otra. Obviamente podemos destacar la inviabilidad de ejecutar decodificadores de altos
órdenes de forma secuencial (en la CPU). Podemos observar el rápido crecimiento del tiempo
de ejecución en la CPU con el incremento del orden.
Figura 6-3. Comparación de las implementaciones sin pérdidas
También hemos querido representar el tiempo de cálculo empleado para las A y B,
donde vemos la penalización que sufre cuando Turbo Códigos de órdenes altos se ejecutan en
la CPU, esto es debido al incremento de las entradas en los bloques ACS. Vemos como al
ejecutarse en la CPU, aplicando el cálculo paralelo del máximo este crecimiento se ve
compensado.
Figura 6-4. Cómputo de las A y B (Sin Sliding Window)
Patricio López Capitulo 6. Resultados de la impementación CUDA
del Turbo Decoder
Noviembre 2011
83
4. Sliding Window
Hasta ahora hemos obtenido resultados de tiempo de simulación para la
implementación sin pérdidas y vemos que la aceleración obtenida no dista demasiado de la
proporcionada por la ejecución del Turbo Decoder aprovechando todas las prestaciones de la
CPU (Intel i7). Seguramente se obtendrían resultados mucho mejores con una tarjeta gráfica
de una gama más alta, pero este no es nuestro caso. De todas formas, las aceleraciones
proporcionadas por la CPU (utilizando los 4 núcleos) se ven ampliamente superadas cuando
aplicamos los algoritmos de sliding window para la paralelización del proceso de
decodificación. Con esta implementación obtenemos aceleraciones de hasta 20 veces respecto
de la CPU con un solo núcleo.
Hemos de tener en cuenta que la aplicación del sliding window no es ideal, modifica el
algoritmo original, y por lo tanto produce pérdidas, aunque como ya hemos visto en capítulos
anteriores, éstas se acotan dentro de unos límites razonables si se escoge correctamente sobre
todo la región de entrenamiento para el cálculo de las métricas.
En la tabla siguiente presentamos resultados de la aplicación del sliding window sobre
la GPU. Donde hemos escogido un período de guarda de 64 bits, suficiente para conservar las
las pérdidas dentro de un margen mínimo.
Tabla 6-4. Tiempo de ejecución paralelización Sliding Window
Ventana Palabra
completa 8192 4096 2048 1024 512 256
Tiempo (s)
18,05 12,16 6,19 3,21 1,70 0,95 0,82
Por lo que finalmente, si comparamos esta implementación (Sliding Window en la GPU
el resultado de aceleración de la ejecución será el siguiente:
Tabla 6-5. Comparativa Siliding WIndow en GPU vs CPU
Arquitectura
CPU CUDA
Intel i7 2.8 GHz 6 GB RAM
NVIDIA GTX 470 (1.2 GHz)
448 CUDA cores
1 core 4 cores Sliding window
Mejores resultados (s)
16,25 4,43 0,82
Patricio López Capitulo 6. Resultados de la impementación CUDA
del Turbo Decoder
Noviembre 2011
84
Tabla 6-6. Aceleración máxima obtenida
CPU 1 core CPU 4 cores
Aceleración maxima obtenida
19,82 5,40
5. Conclusión
Con la conclusión de este capítulo damos por cerrado el primer punto sobre los que se
centra este trabajo. Donde hemos propuesto un método para reducir el tiempo de ejecución
del Turbo Decoder utilizando la herramienta CUDA. En los resultados reportamos una
importante aceleración para los Turbo Códigos binarios, duo binarios e incluso para los
ternarios, que de hecho son los más estudiados y barajados como candidatos para ser
incluidos en los últimos estándares de comunicaciones inalámbricas.
En los resultados de simulación se puede observar una reducción drástica del tiempo
de ejecución simplemente independizando el cálculo de las branch metrics y realizando el
cálculo de éstas sobre la tarjeta gráfica, ya que en esta etapa del algoritmo MAP encontramos
una gran densidad de cálculos. Las branch metrics son totalmente paralelizables ya que no
dependen de resultados en instantes de tiempo diferentes al actual. Aunque para órdenes de
TC altos esta aproximación deja de ser eficiente debido al alto número de métricas a calcular y
luego transferir hacia la memoria de la CPU, así como el incremento de la dimensión de los
bloques ACS al elevar el orden. Por ello hemos desarrollado una segunda aproximación que
compensa estas pérdidas de prestaciones (en tiempo de ejecución) y consigue muy buenos
resultados incluso para altos órdenes del TC.
Si bien las aceleraciones obtenidas con estas aproximaciones no distan demasiado de
las prestaciones proporcionadas por la ejecución de dicho código paralelo sobre los 4 núcleos
de la CPU. Existen GPU con bastante más capacidad que la utilizada para las simulaciones.
En cambio, si añadimos un grado más en la paralelización del Turbo Decoder,
aplicando algoritmos de sliding window, la aceleración obtenida con la GPU se incrementa
sustancialmente, obteniendo aceleraciones de hasta 20 veces.
Capítulo 7. Análisis de prestaciones del Turbo Decoder en punto fijo
1. INTRODUCCIÓN ..................................................................................................................... 86
2. SIMPLIFICACIONES DEL ALGORITMO MAP .................................................................................. 86
3. MÉTRICAS PROVISTAS POR EL DEMAPPER ................................................................................... 86
4. IMPLEMENTACIÓN DEL TURBO DECODER EN PUNTO FIJO ............................................................... 88
4.1. Representación ........................................................................................................ 88
4.2. Cuantización de la función de corrección para el máximo ...................................... 89 4.2.1. Aproximación con Look Up Table ..................................................................................... 89 4.2.2. Aproximación Constant-Log-MAP .................................................................................... 93
4.3. Otras consideraciones ............................................................................................. 93 4.3.1. Bits parte fraccionaria ...................................................................................................... 93 4.3.2. Bucle de decodificación .................................................................................................... 94
5. RESULTADOS FINALES DE LA IMPLEMENTACIÓN EN PUNTO FIJO DEL TURBO DECODER .......................... 95
5.1. Diferencia prestaciones max/max* ......................................................................... 95
5.2. Resultados de pérdidas totales ................................................................................ 95
6. CONCLUSIÓN ........................................................................................................................ 97
Patricio López Capitulo 7. Análisis de prestaciones del Turbo
Decoder en punto fijo
Noviembre 2011
86
1. Introducción
Para conseguir un Turbo Decoder eficiente en punto fijo es importante desarrollar
algoritmos precisos y de baja complejidad utilizando una cuantización con el mínimo número
de bits posible. Este mismo objetivo se ha enmarcado en el proyecto de diseño del receptor de
DVB-SH, cuyo FEC está basado en un turbo código y del que se realizó una versión en punto fijo
para su posterior implementación.
Dado que muchos de los razonamientos y observaciones que añadimos a lo largo de
este capítulo se corresponden con resultados exclusivamente empíricos hemos visto adecuado
intercalar los resultados de simulaciones a lo largo del mismo. Todos estos resultados son fruto
de las simulaciones realizadas en el proceso de diseño del Turbo Decoder para DVB-SH.
2. Simplificaciones del algoritmo MAP
Como ya hemos explicado a lo largo del trabajo, el algoritmo MAP (Maximum a
Posteriori) para el diseño de los decodificadores SISO en los Turbo Decoder, se considera como
el algoritmo óptimo. Aunque como también hemos explicado, se trata de un algoritmo costoso
tanto en términos software como hardware debido a la representación numérica de las
probabilidades, la necesidad de utilizar funciones no lineales como la exponencial y la
existencia de un gran número de multiplicaciones. Esto ha desembocado en la utilización de
algoritmos subóptimos que operan enteramente en el dominio logarítmico. Los algoritmos
Log-MAP presentan unas prestaciones equivalentes a su formulación original.
La complejidad del algoritmo Log-MAP viene marcada por la operación logaritmo de la
suma de exponenciales, fruto de la necesidad del cómputo de tanto los LLR de salida como de
las métricas A y B.
Este bloque funcional se puede aproximar por la siguiente función,
Donde se puede resolver de diferentes formas, bien aplicando una Look Up Table
(LUT) u otras técnicas como la aproximación constant-Log-MAP, que explicaremos más
adelante.
3. Métricas provistas por el demapper
Es de vital importancia el formato con el que se pasen las métricas del canal obtenidas
por el demapper hacia el Turbo Decoder. Tienen una fuerte dependencia tanto del escalado
como del número de bits que se dediquen a la parte fraccionaria.
En nuestro caso hemos realizado simulaciones para el conjunto demapper-Turbo
Decoder del estándar DVB-SH, obteniendo los siguientes resultados de pérdidas tras al utilizar
Patricio López Capitulo 7. Análisis de prestaciones del Turbo
Decoder en punto fijo
Noviembre 2011
87
un demapper en punto fijo (el Turbo Código se mantiene en punto flotante con su
implementación ideal.
Tabla 7-1. Pérdidas demapper punto fijo. LLR 10 bits. QPSK
Code Rate Fixed Point Demapper Loss
1/5 0.3016
2/5 0,0520
1/2 0,0503
Tabla 7-2. Pérdidas demapper punto fijo. LLR 10 bits. 16-QAM
Code Rate Fixed Point Demapper Loss
1/5 0,1637
2/5 0,0250
1/2 0,2183
Sobre los resultados anteriores habrá que aplicar una pérdida extra, ya que para los
requisitos de área un diseño con 10 bits supone sobrepasar con creces las limitaciones en este
aspecto. 5 o 6 bits para la representación de los LLR de salida del demapper suelen ser
adecuados, siempre en conjunto con un escalado y un número de bits adecuados para la parte
fraccionaria.
A continuación presentamos las pérdidas fruto de esta reducción. En nuestro caso
daremos los LLR con 5 bits.
Tabla 7-3. Pérdidas extra LLR 5 bits. QPSK
Code Rate Fixed Point 5 bits
1/5 0,0284
2/5 0,0375
1/2 0,0260
Tabla 7-4. Pérdidas extra LLR 5 bits. 16-QAM
Code Rate Fixed Point 5 bits
1/5 0,0875
2/5 0,0560
1/2 0,0907
Una vez hemos analizado el efecto de la representación en punto fijo proveniente del
demapper, estamos en condiciones de atacar al problema de la cuantización del Turbo
Decoder.
Patricio López Capitulo 7. Análisis de prestaciones del Turbo
Decoder en punto fijo
Noviembre 2011
88
4. Implementación del Turbo Decoder en punto fijo
Para la implementación del Turbo Decoder binario, independientemente de la
modulación que realmente apliquemos (QPSK, 8PSK, 16-QAM, …), el diseño se realiza de forma
binaria, es decir tomaremos los bits codificados y los mapearemos de forma bipolar (-1, +1). A
su vez, los primeros diseños se conciben para un canal AWGN con varianza . Los valores soft
que obtendremos del canal en el receptor se interpretarán como el nivel de señal transmitido
más un ruido aditivo:
Como el decoder funcionará en el dominio logarítmico, y como ya hemos visto en otros
apartados de este trabajo, la entrada el decoder se proporcionará normalmente en la forma
log-likelihood ratio (LLR). Esta transformación es necesaria para asegurar que la ganancia del
canal y la varianza del ruido se tienen en cuenta de forma correcta.
Por lo que los coeficientes generados por el demapper experimentan la siguiente
transformación:
Donde es un factor que representa la fiabilidad del canal.
4.1. Representación
En la siguiente figura representamos un diagrama de bloques de la estructura
propuesta para la simulación del Turbo Decoder en punto fijo.
El primer paso en el diseño de un decoder en punto fijo es determinar el método de
cuantización requerido para representar los valores soft que obtenemos del canal como
valores enteros. Las cantidades en punto fijo se caracterizan por la longitud de la palabra en
bits, la posición de la coma, y si son cantidades representadas con o sin signo.
En nuestro caso hemos escogido una representación complemento a 2 con signo para
la representación de los soft bits . La longitud de palabra se presenta en el formato ,
con un bit de signo, bits para representar la parte entera y bits para representar la parte
fraccionaria de cada cantidad. Se utilizan distintos modos de cuantización para determinar lo
que ocurre cuando se requiere una precisión de bits mayor de la disponible. Normalmente se
suele utilizar un redondeo hacia el infinito, esto es al valor más cercano a infinito si positivo o a
menos infinito en el caso de que este valor sea negativo tras el escalado.
En otras publicaciones [35] se indica que desde la perspectiva de implementación, la
función no lineal de corrección para la función del máximo, es la única operación en el
algoritmo Log-MAP necesita la magnitud exacta de la métrica proveniente del canal . Las
otras dos operaciones (el máximo y la suma) son invariantes ante los cambios de escala.
Patricio López Capitulo 7. Análisis de prestaciones del Turbo
Decoder en punto fijo
Noviembre 2011
89
Teniendo en cuenta esto, se puede llegar a la conclusión de que el algoritmo Log-MAP
exacto y por lo tanto el Turbo Decoder en su conjunto, pueden operar con precisión sobre los
valores no escalados , simplemente utilizando una pequeña modificación de la expresión
inicial:
En [34] han comprobado que esta nueva definición del máximo trabaja exactamente
igual, es decir, la nueva corrección es equivalente. Por pequeña que parezca, esta
simplificación ayuda a reducir el número de bits necesarios para representar las métricas en el
decoder.
SISO decoder
SISO decoder
SAT SAT
1p
ky
2p
ky
s
ky
Lc
Lc
kx̂
i
1
i
2
1
o
1
o
2
e
1
e
2
Figura 7-1. Esquema del Turbo Decoder para su implementación en punto fijo
4.2. Cuantización de la función de corrección para el máximo
El bloque con las operaciones logaritmo de suma de exponenciales correspondientes a
la función de corrección del algoritmo Log-MAP siguen aun así representando un problema
debido a su naturaleza no lineal. En este apartado se analizan las distintas aproximaciones que
se han realizado para obtener una cuantización de dicha corrección que nos proporcione los
resultados óptimos.
4.2.1. Aproximación con Look Up Table
Existen diversas formas de resolver vía hardware dicha función, una de ellas es la
definición de esta función de corrección por medio de una LUT, aunque esta solución continúa
Patricio López Capitulo 7. Análisis de prestaciones del Turbo
Decoder en punto fijo
Noviembre 2011
90
siendo algo compleja, ya que la construcción de diversos bloques de la función de corrección
implica duplicar dicha tabla. Desde un punto de vista software, los accesos no secuenciales a
memoria resultantes del indexado de la tabla pueden introducir necesarios puntos de espera e
incrementar el tiempo de ejecución.
En la siguiente figura podemos ver la representación de la función de corrección,
donde hemos superpuesto la función ideal y una cuantización con 16 entradas (salidas en
flotante). Inicialmente representamos la función simplemente cuantizando la entrada,
mantenemos los valores de la salida no cuantizados (pueden tomar cualquier valor del rango).
Hemos observado obtener buenos resultados con 4 bits a la entrada (16 valores)
Figura 7-2. Función de corrección. Cuantizado eje X. Salidas en flotante
Posteriormente pasamos a cuantizar la salida. En la Figura 7-3 y en la Figura 7-4 se
representan de forma gráfica las aproximaciones de la función de corrección aplicando 4 y 3
bits a la salida.
Patricio López Capitulo 7. Análisis de prestaciones del Turbo
Decoder en punto fijo
Noviembre 2011
91
Figura 7-3. Aproximación de la función de corrección con 4 bits
Figura 7-4. Aproximación de la función de corrección con 3 bits
Según realicemos la cuantización de los elementos de la LUT obtendremos mejores o
peores prestaciones. A continuación presentamos algunos resultados de una serie rápida de
simulaciones, donde vemos la degradación de la BER para una C/N dada. Hemos simulado el
Code Rate 1/5 con una modulación QPSK. La BER de referencia para una función max* ideal es
4,8∙10-3 y a continuación presentamos la degradación.
Patricio López Capitulo 7. Análisis de prestaciones del Turbo
Decoder en punto fijo
Noviembre 2011
92
Tabla 7-5. Número de bits para los valores de la LUT. Degradación de la BER
Nº de bits BER
floor ceil
2 1,7∙10-2
3 7,2∙10-3 8,4∙10-3
4 5,2∙10-3 4,9∙10-3
5 5,0∙10-3 4,9∙10-3
6 4,8∙10-3 4,9∙10-3
7 4,9∙10-3 4,9∙10-3
Vemos que la degradación mayor se produce al pasar de 4 a 3 bits. También se
obtienen resultados ligeramente diferentes en función de cómo se haya realizado la
cuantización (floor o ceil).
También se ha probado que si escogemos una implementación con pocos bits, esta
degradación es mucho menor si conservamos una entrada para el máximo de la función. Por
ejemplo:
Tabla 7-6. Entrada extra para el máximo de la función de la corrección. Degradación de la BER
Nº d bits Nº entradas LUT BER degradada
1 bit 3 entradas (2 + una fija para el máximo) 7,5∙10-3
2 bits 5 entradas (4 + otra para el máximo) 4,9∙10-3
Donde vemos que la degradación de la BER es considerablemente menor que la que
reportábamos en la tabla anterior. Este aspecto nos permitiría incluso conseguir buenas
prestaciones simplemente con un bit.
A continuación vemos un par de ejemplos más de cómo resultaría la aproximación de
la función.
Figura 7-5. Función de corrección. 2 entradas
Patricio López Capitulo 7. Análisis de prestaciones del Turbo
Decoder en punto fijo
Noviembre 2011
93
Figura 7-6. Función de corrección 3 entradas.
4.2.2. Aproximación Constant-Log-MAP
Otra posible solución es la aplicación de la siguiente función de corrección
Conocida como constant-Log-MAP. En [34] se ha probado que un valor de 0.5 para la
constante C y 1.5 para T, son bastante efectivos y proporcionan unas magníficas prestaciones
dentro de un amplio rango de SNR y distintos tamaños de palabra de código. En el caso de
seleccionar este tipo de implementación para la función de corrección, cada vez que se invoca
la función , en lugar de escalar el valor absoluto de la diferencia de los operandos por
y luego volver a desescalar el resultado, simplemente se procederá a aplicar un escalado a C y
T cuando se detecte una variación en la SNR. Los valores en punto fijo de las constantes
escaladas se pasarán al decoder como parámetros.
4.3. Otras consideraciones
4.3.1. Bits parte fraccionaria
También será importante evaluar el efecto de la longitud asignada en número de bits a
la parte fraccionaria de nuestra métrica. En [34] , esta tarea se lleva a cabo evaluando las
prestaciones individualmente de cada decoder que conforman el Turbo Decoder (sólo de uno
de ellos, ya que los decoders que conforman el Turbo Código suelen ser el mismo). De la
misma manera, estas pruebas realizadas individualmente sobre el decodificador SISO también
Patricio López Capitulo 7. Análisis de prestaciones del Turbo
Decoder en punto fijo
Noviembre 2011
94
permiten validar las prestaciones de la aproximación constant-Log-MAP (para la decodificación
de un código convolucional, por supuesto).
En relación con los bits de la parte fraccionaria, diversas pruebas muestran que la
reserva de un mínimo de 2 bits asegura unas prestaciones muy próximas a las conseguidas con
el Turbo Decoder en punto flotante.
4.3.2. Bucle de decodificación
El próximo paso en el proceso de diseño del Turbo Decoder en punto fijo, será evaluar
los efectos de esta representación cuantizada sobre el bucle que realiza la decodificación
iterativa.
Las métricas generadas por cada uno de los decoders, conocidas como valores a
posteriori (en su formato Log-Likelihood), se pueden descomponer en tres términos
Donde y representan la información a priori y extrínseca
asociadas al bit respectivamente. El valor es la información extrínseca producida por el
segundo decoder y realimentada hacia el primer decoder como información a priori. De forma
previa a la primera iteración es inicializada a 0, ya que el decoder 2 no ha actuado aún
sobre los datos. Tras cada iteración completa, los valores se actualizan de manera que
reflejan la fiabilidad de los valores de salida, trasladando esta información al primer decoder.
Dicha información generada hacia el primer decoder, se obtiene simplemente de la suma de
con la información sistemática (si estamos opernado claro en el dominio logarítmico).
Tras este pequeño recordatorio del funcionamiento básico del Turbo Decoder,
tendremos que analizar dos factores fundamentales que influyen en el correcto
funcionamiento del decoder:
Habrá que tener en cuenta que las operaciones aritméticas utilizarán un número
mayor de bits al generar resultados intermedios (en la práctica 2 o 3 bits más en comparación
con la longitud predefinida para todas las variables). Los casos de desbordamiento se tratarán
solamente en la asignación del resultado final.
Los valores LLR correspondientes a la información extrínseca deben ser saturados de
manera previa a las demás cantidades, en otras palabras, su número de bits debe ser inferior
al resto de las métricas. Este es el único método que garantiza que las magnitudes de la
entrada de los decoders SISO son inferiores a las magnitudes de la salida. Este requisito es
fundamental para que el signo de la información extrínseca continúe expresando la fiabilidad
de sus valores binarios correspondientes, 0 o 1, en caso contrario, el decoder introduciría
errores. Podemos visualizar fácilmente los efectos de esta técnica al limitar dentro de un rango
los valores de los LLR extrínsecos en la implementación de punto flotante. Donde también se
demuestra un importante efecto de este rango de saturación sobre el suelo que se produce en
la curva de BER.
Patricio López Capitulo 7. Análisis de prestaciones del Turbo
Decoder en punto fijo
Noviembre 2011
95
5. Resultados finales de la implementación en punto fijo del
Turbo Decoder
Para completar el último paso en la cuantización del Turbo Decoder presentaremos los
resultados de pérdidas totales en el sistema por la influencia de la inclusión del diseño en
punto fijo del Turbo Decoder.
5.1. Diferencia prestaciones max/max*
Para nuestro diseño, finalmente se escogió representar la función de aproximación con
una LUT de 8 entradas con valores de 6 bits. En las siguientes tablas podemos observar la
penalización sufrida en el caso de que no apliquemos dicha LUT con la corrección para la
función del máximo.
Vemos que podemos llegar a tener unas pérdidas de hasta 0,3 dB (tercera columna) de
no aplicar esta función de corrección. La segunda columna representa la diferencia de
prestaciones entre el Turbo Decoder en flotante y el Turbo Decoder en punto fijo.
Tabla 7-7. Pérdidas max y max*. QPSK
Code Rate Aproximación max* Max-Log Ideal
1/5 0,05 0
2/5 0,3125 0,25
1/2 0,2741 0,002
Tabla 7-8. Pérdidas max y max*. 16-QAM
Code Rate Aproximación max* Max-Log Ideal
1/5 0,45 0,1498
2/5 0,5015 0,305
1/2 0,1675 0,1166
5.2. Resultados de pérdidas totales
A continuación presentamos los resultados totales de pérdidas, donde hemos
evaluado el sistema sobre un canal AWGN y un canal COST207 con 100 Hz de Doppler.
Como última apreciación sobre la implementación del Turbo Decoder nos gustaría
señalar el ajuste realizado en lo que se refiere al número máximo de iteraciones que puede
efectuar el Turbo Decoder. Este parámetro será variable en función de la constelación y del
Code Rate utilizado, y vendrá acotado por los requisitos de throughput del sistema para dicha
configuración.
Las simulaciones ideales, tomadas como referencia, han sido realizadas con 8
iteraciones, tal y como viene establecido en las guías de implementación del estándar DVB-SH.
En la Tabla 7-9 presentamos los resultados de la cuantización del sistema completo,
donde vemos que las pérdidas finales de implementación en la mayor parte de los casos no
Patricio López Capitulo 7. Análisis de prestaciones del Turbo
Decoder en punto fijo
Noviembre 2011
96
sobrepasan 1 dB de pérdidas y que en una gran parte de ellos, sobre todo en QPSK, las
pérdidas están alrededor de 0.5 dB.
Tabla 7-9. Resultados pérdidas TBDC en punto fijo. Canal AWGN
Modulation CodingRate FFT + CP N. Iterations C/N Ideal 8
It C/N Min
FP Imp. Losses
QPSK
1/2 2K 1/4 21 1,50 1,83 0,34
2/5 2K 1/4 27 0,10 0,68 0,58
1/3 2K 1/4 33 -0,96 -0,49 0,47
2/7 2K 1/4 39 -1,78 -1,25 0,53
1/4 2K 1/4 43 -2,46 -1,86 0,60
2/9 2K 1/4 49 -3,04 -2,40 0,64
1/5 2K 1/4 55 -3,56 -2,85 0,71
16-QAM
1/2 2K 1/4 10 6,81 7,79 0,98
2/5 2K 1/4 13 5,06 6,33 1,26
1/3 2K 1/4 16 3,80 4,70 0,90
2/7 2K 1/4 19 2,80 3,70 0,90
1/4 2K 1/4 21 2,10 2,70 0,60
2/9 2K 1/4 24 1,30 2,05 0,75
1/5 2K 1/4 27 0,73 1,50 0,77
En la Tabla 7-10 presentamos los resultados para un canal COST207, donde vemos que
las pérdidas por la cuantización son sustancialmente mayores que en el canal AWGN, dado que
aquí entra en juego de manera importante la cuantización de la información del canal (CSI).
Tabla 7-10. Resultados pérdidas TBDC en punto fijo. Canal COST207
Modulation CodingRate FFT + CP N. Iterations C/N Ideal
8 It C/N Min FP Imp. Losses
QPSK
1/2 2K 1/4 21 3,71 4,90 1,19
2/5 2K 1/4 27 1,90 3,35 1,45
1/3 2K 1/4 33 0,41 1,60 1,19
2/7 2K 1/4 39 -0,53 0,80 1,33
1/4 2K 1/4 43 -1,32 -0,05 1,27
2/9 2K 1/4 49 -2,10 -0,65 1,45
1/5 2K 1/4 55 -2,70 -1,18 1,53
16-QAM
1/2 2K 1/4 10 8,69 12,20 3,50
2/5 2K 1/4 13 6,77 9,70 2,93
1/3 2K 1/4 16 5,19 7,10 1,90
2/7 2K 1/4 19 4,09 5,80 1,71
1/4 2K 1/4 21 3,05 4,49 1,44
2/9 2K 1/4 24 2,24 3,70 1,45
1/5 2K 1/4 27 1,60 2,99 1,39
Patricio López Capitulo 7. Análisis de prestaciones del Turbo
Decoder en punto fijo
Noviembre 2011
97
Los resultados presentados en las tablas anteriores representan las pérdidas
establecidas por el simulador, sobre cuyos algoritmos en punto fijo se ha derivado la
implementación hardware final. Hemos de apuntar que en el modelo de simulación no se han
incluido algunas funcionalidades hardware con una aportación sistemática en la reducción de
las pérdidas, por lo que los resultados finales de pérdidas hardware quedan incluso menores a
los establecidos por la simulación, tal y como podemos ver en la Tabla 7-11.
Tabla 7-11. Pérdidas de implementación HW
Modulation CodingRate C/N Ideal
C/N Impl. Imp. Losses
QPSK
1/2 1.4 1.5 0.1
1/3 -0.9 -0.8 0.1
1/4 -2.5 -2.4 0.1
1/5 -3.6 -3.5 0.1
16-QAM
1/2 6.8 6.9 0.1
1/3 3.7 3.9 0.2
1/4 1.9 2.1 0.2
1/5 0.7 0.9 0.2
6. Conclusión
En este capítulo hemos explicado un procedimiento para diseñar el Turbo Decoder en
punto fijo y obteniendo unas pérdidas en las prestaciones aceptablemente pequeñas.
Se ha estudiado cuales son los puntos clave a la hora de cuantizar el Turbo Código, de
manera que tengamos un modelo lo más fiel posible de cara a su implementación hardware.
Su estudio es especialmente complejo debido a la existencia de funciones no lineales y de
distintas aproximaciones del algoritmo, así como de su naturaleza iterativa.
Patricio López Conclusión Noviembre 2011
98
Capítulo 8. Conclusión
RESULTADOS ................................................................................................................................ 99
TRABAJO FUTURO........................................................................................................................ 100
Patricio López Conclusión Noviembre 2011
99
En este trabajo se ha estudiado e implementado un método para acelerar la ejecución
software del Turbo Decoder. Como motivación, hemos tenido en cuenta la necesidad de
reducir los tiempos de simulación de los sistemas de comunicaciones, fundamentalmente para
optimizar las fases de desarrollo de los estándares así como la etapa de diseño; ya por parte de
cada fabricante; de los diferentes dispositivos de comunicaciones. Aunque, la aplicación de
este trabajo no sólo se reduce a una aceleración de los tiempos de simulación, actualmente los
dispositivos Software Defined Radio han cobrado importancia y ha aparecido la necesidad de
implementar un procesamiento software de la señal que cumpla los requisitos de latencia y
throughput en tiempo real establecidos por los estándares.
A lo largo de este proyecto hemos estudiado la complejidad de los Turbo Códigos, en
concreto su fase de decodificación, la cual acumula una gran densidad de cálculos, así como
complejos algoritmos con una fuerte dependencia entre cálculos intermedios, lo que hace
bastante complicada su paralelización y por lo tanto es indispensable un completo análisis
previo.
Hemos analizado los puntos paralelizables del Turbo Decodificador y propuesto e
implementado tres propuestas que progresivamente incluyen un grado mayor de
paralelización. Son las siguientes:
Paralelización del cálculo de las métricas asociadas a las transiciones del trellis
Paralelización del cálculo de las métricas de las transiciones más el cálculo de
las Backward y Forward metrics.
Paralelización aplicando el método de Sliding Window. Introduce pérdidas
aceptables.
Estos tres métodos han sido implementados utilizando la herramienta CUDA,
proporcionada por NVIDIA y que permite aprovechar los recursos de la tarjeta gráfica.
Adicionalmente, en este proyecto se han analizado las prestaciones del Turbo Decoder
de DVB-SH en su modelo cuantizado. Para ello se han estudiado los puntos de mayor influencia
a la hora de introducir las pérdidas, sobre todo las introducidas por la cuantización de la
función de corrección a la función de aproximación max-log.
Resultados
Si observamos los resultados obtenidos, vemos que los más prometedores se obtienen
al aplicar una paralelización completa incluyendo el algoritmo Sliding Window. Mediante la
aplicación de éste podemos obtener aceleraciones de hasta 20 veces, lo que nos permite,
jugando con las diferentes posibilidades que ofrece este algoritmo en cuanto a tamaño de
ventana y período de entrenamiento, obtener tasas de transmisión que cumplen con los
requisitos de los estándares que incluyen TC.
Si aplicamos una paralelización sin pérdidas, es decir, aplicamos uno de los dos
primeros métodos anteriormente citados, la aceleración máxima se reduce a algo más de 4
Patricio López Conclusión Noviembre 2011
100
veces, la cual, si la comparamos con la obtenida al utilizar simplemente todos los recursos
proporcionados por la CPU (en nuestro caso, los 4 cores), es prácticamente nula.
En lo que se refiere al análisis en punto fijo del Turbo Decoder de DVB-SH, hemos visto
que las párdidas introducidas por la cuantización para un canal AWGN son menores que 1dB,
con casos en los que úncamente perdemos alrededor de 0.3 dB, por lo que se puede decir que
ante la exhaustiva reducción de área y cuantización del receptor, se cumplen con margen los
requisitos máximos de pérdidas.
Trabajo futuro
En la introducción de este proyecto hemos señalado la importancia de optimizar dos
puntos clave en la ejecución software de los receptores, por un lado el decodificador FEC y por
otro el detector MIMO. Actualmente ya estamos trabajando en la reducción de la complejidad
del proceso de detección MIMO, estudiando la viabilidad de diferentes algoritmos así como su
implementación aprvechando los recursos de la tarjeta gráfica. Este trabajo no sólo conllevará
un beneficio en lo que se refiere a software. El estudio llevado a cabo ayudará a la elección de
los algoritmos óptimos para su inclusión en futuros receptores, o lo que es lo mismo, el estudio
de complejidad software realizado se mapeará de forma directa en los futuros esfuerzos que
se realicen para la implementación hardware de los nuevos sistemas de comunicaciones.
Al mismo tiempo se abren líneas de trabajo de gran interés, sobre todo en el campo
relacionado con Software Defined Radio, ya que los resultados obtenidos en este trabajo
tienen una aplicación directa, pues este tipo de receptores precisan de algoritmos software
que cumplan requisitos de latencia y throughput nomalmente inalcanzables para los
algoritmos ejecutados de forma clásica sobre una CPU.
Patricio López Referencias Noviembre 2011
101
Capítulo 9. Referencias
[1] DVB. Commercial Requirements for DVB-NGH. DVB CM-NGH. Version 1.01
[2] Universal Mobile Telecommunications System (UMTS); Technical Specifications and
Technical Reports for a UTRAN-based 3GPP system (3GPP TS 21.101 version 8.3.0
Release 8). ETSI TS 121 101 V8.3.0 (2011-07)
[3] IEEE Standard for Local and metropolitan area networks Part 16: Air Interface for
Broadband Wireless Access Systems. E-ISBN : 978-0-7381-5919-5. 2009
[4] Gerard J. Foschini. Layered space–time architecture for wireless communication in a
fading environment when using multiple antennas. Bell Labs Technical Journal. Autumn
1996.
[5] R.G. Gallager, Low Density Parity Check Codes, Monograph. M.I.T. Press, 1963.
[6] C. Berrou, A. Glavieux and P. Thitimajshima, Near Shannon Limit Error-Correcting
Coding and Decoding: Turbo Codes. IEEE International Conference on Communications,
pp. 1064-1070, 1993.
[7] Oliver Haffenden. DVB-T2: The Common Simulation Platform. Research White Paper.
WHP 196. BBC.
[8] www.GPGPU.org
[9] NVIDIA CUDA C Programming Guide. NVIDIA CUDATM. Version 4.0. June 2011
[10] Accelerating MATLAB with CUDATM Using MEX Files. White Paper. September 2007
[11] CUDA C best practices guide. Design Guide. Version 4.0. March 2011
[12] Gene Amdahl. Validity of the Single Processor Approach to Achieving Large-Scale
Computing Capabilities. AFIPS Conference Proceedings, (30), pp. 483-485, 1967.
Patricio López Referencias Noviembre 2011
102
[13] NVIDIA’s next generation CUDATM compute architecture: FermiTM .White paper.
[14] FermiTM Compatibility Guide for CUDA Applications. NVIDIA CUDATM. August 2010
[15] Richard Hamming. Error Detecting and Error Correcting Codes. Bell Systems Technical
Journal, Vol 29, pp 147-160, Apr. 1950
[16] ZTE Corporation. Comparison of structured LDPC Codes and 3GPP Turbo codes. R1-
050840, 2005.
[17] T. Lestable, E. Zimmerman, M. Hamon and S. Stiglmayr. Block-LDPC Codes vs Duo-
Binary Turbo-Codes for European Next Generation Wireless Systems. IEEE Vehicular
Technology Conference, pp. 1-5, September 2006.
[18] European Telecommunications Standard Institute ETSI York. Digital Video Broadcasting
(DVB); Framing structure, channel coding and modulation for Satellite Services to
Handheld devices (SH) below 3GHz. EN 302 583 V.1.1.1., March 2008.
[19] European Telecommunications Standard Institute ETSI York. Digital Video Broadcasting
(DVB); Interaction channel for satellite distribution systems. EN 301 790 V1.5.1., May
2009.
[20] G.D.Forney, Jr. The Viterbi Algorithm. IEEE Proceedings, Vol.61, pp. 268-279, March
1973
[21] J. Hagenauer, E. Offer and L. Papke. Iterative decoding of binary block and
convolutional codes. IEEE Transactions on Information Theory, vol. 42, no. 2, March
1996.
[22] J. Hagenauer, P. Hoeher, A Viterbi Algorithm with Soft-Decision Outputs and its
Applications The Soft-Output Symbol-by-Symbol MAP and Viterbi algorithm (SOVA).
Proc. IEEE Global Telecommunications Conference, pp. 1680–1686. November 1989.
[23] L. Bahl, J. Cocke, F. Jelinek, and J. Raviv. Optimal Decoding of Linear Codes for
minimizing symbol error rate. IEEE Transactions on Information Theory, vol. IT-20(2),
pp. 284-287, March 1974.
[24] Yingzi Gao and M. R. Soleymani. Triple-binary Circular Recursive Systematic
Convolutional Turbo Codes. Proceedings of the 5th International Symposium on
Wireless Personal Multimedia Communications (WPMC ’02), vol. 3, pp. 951–955,
Honolulu, Hawaii, USA, October 2002.
Patricio López Referencias Noviembre 2011
103
[25] C. Berrou, M. Jézéquel, C. Douillard and S. Kerouédan. The advantages of non-binary
turbo codes. Information Theory Workshop Proceedings, Cairns, Australia, pp. 61-63,
September 2001.
[26] DVB. Guidelines for Implementation for Satellite Services to Handheld devices (SH)
below 3GHz.TS 102 584 V1.2.1 (01/11)
[27] DVB. Guidelines for the Implementation and Usage of the DVB Interaction Channel for
Satellite Distribution Systems. TR 101 790 V1.4.1 (07/09)
[28] G. Fettweis and H. Meyr. Parallel Viterbi Algorithm Implementation: Breaking the ACS-
Bottleneck. IEEE Transactions on Communications. vol. 37, pp. 785-790, August 1989
[29] Ming Li; Ming-ming Peng; Jing-sai Jiang; Fa-yu Wan. A Pipeline Sliding Window Max-
Log-Map Turbo Decoder. High Density packaging and Microsystem Integration, 2007.
HDP '07. International Symposium on , vol., no., pp.1-4, 26-28 June 2007
[30] Chao Cheng; Parhi, K.K. Hardware Efficient Low-Latency Architecture for High
Throughput Rate Viterbi Decoders. Circuits and Systems II: Express Briefs, IEEE
Transactions on , vol.55, no.12, pp.1254-1258, Dec. 2008
[31] M. Marandian, J. Fridman, Z. Zvonar, and M. Salehi, "Performance Analysis of Sliding
Window Turbo Decoding Algorithms for 3GPP FDD Mode", presented at IJWIN, 2002,
pp.39-54.
[32] R. Dobkin and M. Peleg. “Parallel Interleaver Design and VLSI Architecture for Low-
Latency MAP Turbo Decoders”, IEEE TRANSACTIONS ON VERY LARGE SCALE
INTEGRATION (VLSI) SYSTEMS, VOL. 13, NO. 4, APRIL 2005, pp 427-438.
[33] Blankenship, T.K.; Classon, B.; , "Fixed-point performance of low-complexity turbo
decoding algorithms ," Vehicular Technology Conference, 2001. VTC 2001 Spring. IEEE
VTS 53rd , vol.2, no., pp.1483-1487 vol.2, 2001
[34] Castellon, M.A.; Fair, I.J.; Elliott, D.G.; , "Fixed-point turbo decoder implementation
suitable for embedded applications," Electrical and Computer Engineering, 2005.
Canadian Conference on , vol., no., pp.1065-1068, 1-4 May 2005
[35] Jung-Fu Cheng; Ottosson, T.; , "Linearly approximated log-MAP algorithms for turbo
decoding," Vehicular Technology Conference Proceedings, 2000. VTC 2000-Spring
Tokyo. 2000 IEEE 51st , vol.3, no., pp.2252-2256 vol.3, 2000
Patricio López Referencias Noviembre 2011
104
[36] B. Classon, K. Blankenship, and V. Desai. Turbo decoding with the constant-Log-MAP
algorithm. In Proceedings of the 2nd International Symposium on Turbo Codes &
Related Topics, pages 467-470, Brest, France, sep. 2000.
[37] SIDSA. S-Band Receiver. Final Report. March 2011. Version 1.0