22 de agosto de 2007

Memoria....¿transaccional?

Sun ha anunciado recientemente una tecnología que, de proporcionar las ventajas que promete, podría marcar una revolución en la manera de afrontar el reto de construir software que aproveche la potencia de los actuales procesadores multicore y sobre todo los futuros, que tendrán decenas o cientos de cores. Como conté aquí, escribir software que utilize técnicas multihilo para aprovechar estos procesadores no solo no es sencillo, sino que es increiblemente complejo e incluso imposible en muchos casos, hasta el punto que algunos sospechan que la apuesta por el multicore acabará en fiasco. Se necesita urgentemente un progreso de algún tipo que permita crear software escalable de forma asequible al programador. La memoria transaccional de Sun quiere ser ese progreso. Pero la cosa no es tan simple: Aparentemente existen implementaciones de memoria transaccional por software, por hardware, e híbridas. Sun parece proponer una solución híbrida. Lo cual deja entreveer que el concepto de memoria transaccional tiene sus cosas.

¿Y qué es eso de la memoria transaccional? Es fácil comprender de que va el concepto atendiendo al significado del nombre, en concreto el de la palabra transacción. En el mundo de las bases de datos, una transacción es un conjunto de operaciones sobre los datos que están garantizadas al 100% que, o se hacen todas a la vez, o no se hacen. Por ejemplo, podría darse el caso de que una empresa necesitara modificar el nombre, la dirección y el teléfono de un cliente en una base de datos . Pues bien, si consideramos como una transacción a la modificación del nombre, la dirección y el teléfono -el programador es quien elige las operaciones que son abarcadas por la transacción- y la base de datos soporta el concepto de transacción y le indicamos que esas operaciones sean una transacción, la base de datos o bien modificará exitosamente todos los campos, o fallará y no modificará ninguno (tambien existe el concepto de "deshacer una transacción"). En el mundo de los sistemas de archivos se ha puesto de moda últimamente el concepto de transacción como método para evitar tener que hacer journaling: ZFS o Reiser 4 o btrfs, por ejemplo, no necesitan journaling, porque las modificaciones críticas al sistema de archivos se hacen de modo transaccional: Se vaya la luz en el momento que se vaya, la estructura y metadatos del sistema de archivos se mantendrán coherentes. NTFS por su parte tiene journaling, pero tambien ha implementado un sistema transaccional respecto a las operaciones que efectua un proceso sobre el sistema de archivos (ZFS sin embargo aunque tiene transaccionalidad respecto a las modificaciones del sistema de archivo en si, no soporta esta transaccionalidad a nivel de procesos).

La cuestión es que aparentemente Sun aparentemente va a añadir soporte de memoria transaccional a sus chips a partir de la segundo mitad del 2008. Esta tecnología permitirá que un proceso pueda marcar como transacción a un conjunto de operaciones que se hagan sobre la memoria. La idea es que esta memoria transaccional sustituya a los locks como sistema para coordinar las operaciones sobre la memoria que comparten. Si puede conseguirlo, a mi no me lo pregunten: Si bien las transacciones pueden utilizarse para garantizar una "atomicidad" de una serie de operaciones, los locks en si tambien son una especie de transacción. Tal como yo lo veo -y no se lo suficiente de bases de datos ni de programación paralela como para poder garantizar que no estoy diciendo una auténtica chorrada-, la ventaja radicaría en que el modelo transaccional permitiría tener a teóricos infinitos procesos progresando individualmente sobre teóricos infinitos cores, y que si alguna de las transacciones es erronea (porque otra transacción ha hecho la misma operacion, por ejemplo) se puede descartar. Esto sería altamente beneficioso en el caso de que no hubiera que descartar muchas transacciones errones: se haría un gran progreso en paralelo.

Pero he aquí que los locks son tambien una especie de transacción atómica sobre una serie de operaciones. La diferencia es que un spinlock o un semáforo o un mutex efectivamente "paran" a todos los demás para garantizar la atomicidad de solamente uno. Se diría por tanto que la memoria transaccional es una técnica "optimista" y destinada a porciones del código con algoritmos específicos que estén diseñados para funcionar con esta técnica y que no vayan a causar que muchas transacciones no sirvan de nada, porque el rendimiento decaería. Los locks sin embargo son "pesimistas" y castigan a todas las CPUs excepto a una. Pero lo cierto es que existen otros sistemas de sincronización que no funcionan exactamente así, en Linux existen técnicas que no se quedan ahí como RCU, que pensándolo ahora se diría que es una especie de técnica relacionada con la memoria transaccional por software y que comparte sus ventajas - de hecho buscando en Google aparece en ciertos foros como proposición de bloque para construir modelos de memoria transaccional por software. RCU es una técnica en la que se hace una copia de la estructura de datos que un proceso determinado va a modificar y modifica esa copia dejando el original intacto, mientras que al mismo tiempo los procesos que tan solo quieren leer la estructura de datos pueden leerla sin sufrir ningún tipo de espera. Una vez modificada la estructura, se modifican unos punteros para que los nuevos lectores que van apareciendo y que quieren leer la estructura, lean la nueva estructura que había sido copiada y modificada, mientras que al mismo tiempo los antiguos lectores que empezaron a leer la estructura antes del cambio siguen leyendo la estructura de datos vieja. Una vez que no queda ningún proceso leyendo la estructura de datos vieja, se borra de la memoria. Sin duda, tiene cierto caracter "transaccional", o al menos permite a infinitos lectores e infinitos escritores estar trabajando simultaneamente sin quedarse bloqueados en una sola CPU.

El caso es que RCU solamente se aplica a ciertas porciones del código, que han sido rediseñadas para aprovechar las ventajas de RCU, no a cualquier lado, y utilizarlo en ciertos sitios sería simplemente absurdo y dañaría el rendimiento: Lo cual demuestra que la memoria transaccional no es simplemente "magia". Pero RCU es una de las claves que permite a Linux funcionar en sistemas con miles de procesadores, lo cual demuestra que a pesar de que no sea "magia", ayuda en gran medida a lidiar con el paralelismo. Y el sistema de Sun, sin ninguna duda, tambien lo hara. Eso si, Linux lleva alguna ventaja a la hora de programar algoritmos que aprovechen estas estructuras, aunque está por ver como ayudará la implementación por hardware de Sun a crear y manejar estas técnicas..

No hay comentarios:

Publicar un comentario en la entrada