Históricamente, la industria de los semiconductores ha sido capaz de ir incrementando la velocidad de reloj de los microprocesadores a medida que se iba doblando el número de transistores a cada nueva generación. Desafortunadamente, debido a problemas relacionados con el consumo energético, la mayoría de los fabricantes de microprocesadores optaron por abandonar esa estrategia y centrarse en microprocesadores multinúcleo. Las GPUs modernas van incluso más allá que los microprocesadores e integran cientos de núcleos con un consumo energético razonable. Debido a este cambio en la industria, las compañías de software se han visto forzadas a adoptar los algoritmos tradicionales secuenciales que estaban diseñados para ser ejecutados en un único núcleo. Este trabajo de paralelización no es tan sencillo como a priori pueda parecer. Por norma general, los humanos estamos acostumbrados a pensar nuestras acciones de forma secuencial. ¿Serías capaz de imaginarte rápidamente cientos de acciones simultáneas en paralelo (algunas de ellas incluso con interdependencias)? La mayoría de las mentes más brillantes del mundo y los programadores no son capaces de ello (y parece razonable). En nuestra vida diaria, tendemos a agobiarnos si tenemos que realizar nueve o diez cosas importantes al mismo tiempo. Parece ser que nuestro cerebro no está diseñado para operar en modo multitarea. Cuantas más tareas intentemos efectuar en paralelo (por ejemplo, contestar un correo electrónico mientras estemos realizando una llamada telefónica), más probable será que cometamos un error debido a haber prestado atención insuficiente. Ésta es la razón por la cual programar código escalable y paralelo para dispositivos como las GPU es un proceso largo y tedioso. Generalmente, cuando escribimos código para estas arquitecturas suele ser problemático y complicado de depurar. No es complicado encontrarse en la situación de tener que dedicar meses programando código paralelo para una operación particular de kernel cuya versión secuencial podría programarse y testearse en un par de días.
En esta nueva era de computación paralela, si una empresa quiere lanzar al mercado un producto software que explote al máximo todas las capacidades del último hardware paralelo disponible en el mercado, sin duda alguna tendrá que invertir más dinero y recursos de los que fueron requeridos en el pasado. Nosotros, en Herta Security, empezamos a adoptar técnicas de paralelización desde el principio en todos nuestros productos. Además, rápidamente nos dimos cuenta de que los algoritmos biométricos pueden beneficiarse de la paralelización de grado fino y de la ejecución de computaciones vectoriales paralelas. Tanto es así, que múltiples etapas del pipeline biométrico tradicional como el proceso de extracción de características es inherentemente paralelo. Sin embargo, la complejidad de los patrones de acceso a memoria de algunas características biométricas hacen que las estrategias de reutilización de datos, caching y prefetching se conviertan en un auténtico reto a la hora de implementarlas. Con la aparición de la computación en GPU, el programador tiene que enfrentarse a millones de hilos de forma concurrente, sincronizarlos, y aprovechar al máximo la arquitectura heterogénea de las memorias cache de estos dispositivos para reducir la latencia tanto como sea posible. Aunque dichas tareas sean lentas y tediosas desde el punto de vista de la investigación y el desarrollo, nos permite a las compañías de software desarrollar productos de buena calidad que escalan correctamente con los últimos avances en hardware. El objetivo último es proporcionar a los clientes una experiencia de usuario imbatible.