stringtranslate.com

Memoria transaccional

En informática e ingeniería , la memoria transaccional intenta simplificar la programación concurrente al permitir que un grupo de instrucciones de carga y almacenamiento se ejecuten de manera atómica . Es un mecanismo de control de concurrencia análogo a las transacciones de bases de datos para controlar el acceso a la memoria compartida en computación concurrente . Los sistemas de memoria transaccional proporcionan una abstracción de alto nivel como alternativa a la sincronización de subprocesos de bajo nivel. Esta abstracción permite la coordinación entre lecturas y escrituras concurrentes de datos compartidos en sistemas paralelos. [1]

Motivación

Atomicidad entre dos transacciones paralelas con un conflicto

En la programación concurrente, la sincronización es necesaria cuando los subprocesos paralelos intentan acceder a un recurso compartido. Las construcciones de sincronización de subprocesos de bajo nivel, como los bloqueos, son pesimistas y prohíben que los subprocesos que están fuera de una sección crítica ejecuten el código protegido por la sección crítica. El proceso de aplicar y liberar bloqueos a menudo funciona como una sobrecarga adicional en cargas de trabajo con poco conflicto entre subprocesos. La memoria transaccional proporciona un control de concurrencia optimista al permitir que los subprocesos se ejecuten en paralelo con una interferencia mínima. [2] El objetivo de los sistemas de memoria transaccional es admitir de forma transparente regiones de código marcadas como transacciones al aplicar atomicidad , consistencia y aislamiento .

Una transacción es una colección de operaciones que pueden ejecutarse y confirmar cambios siempre que no exista un conflicto. Cuando se detecta un conflicto, una transacción volverá a su estado inicial (antes de cualquier cambio) y se volverá a ejecutar hasta que se eliminen todos los conflictos. Antes de una confirmación exitosa, el resultado de cualquier operación es puramente especulativo dentro de una transacción. A diferencia de la sincronización basada en bloqueos, donde las operaciones se serializan para evitar la corrupción de datos, las transacciones permiten un paralelismo adicional siempre que pocas operaciones intenten modificar un recurso compartido. Dado que el programador no es responsable de identificar explícitamente los bloqueos o el orden en que se adquieren, los programas que utilizan memoria transaccional no pueden producir un punto muerto . [2]

Con estas construcciones en su lugar, la memoria transaccional proporciona una abstracción de programación de alto nivel al permitir a los programadores encerrar sus métodos dentro de bloques transaccionales. Las implementaciones correctas garantizan que los datos no se puedan compartir entre subprocesos sin pasar por una transacción y producir un resultado serializable . Por ejemplo, el código se puede escribir como:

def  transfer_money ( desde_cuenta ,  a_cuenta ,  monto ): """Transferir dinero de una cuenta a otra.""" with transaction (): desde_cuenta . balance -= monto a_cuenta . balance += monto         

En el código, el bloque definido por "transacción" tiene garantizada la atomicidad, la consistencia y el aislamiento de la implementación de la memoria transaccional subyacente y es transparente para el programador. Las variables dentro de la transacción están protegidas de conflictos externos, lo que garantiza que se transfiera la cantidad correcta o que no se realice ninguna acción. Tenga en cuenta que los errores relacionados con la concurrencia aún son posibles en programas que utilizan una gran cantidad de transacciones, especialmente en implementaciones de software donde la biblioteca proporcionada por el lenguaje no puede imponer un uso correcto. Los errores introducidos a través de transacciones a menudo pueden ser difíciles de depurar, ya que no se pueden colocar puntos de interrupción dentro de una transacción. [2]

La memoria transaccional es limitada, ya que requiere una abstracción de memoria compartida. Aunque los programas de memoria transaccional no pueden producir un bloqueo, los programas pueden sufrir un bloqueo activo o una falta de recursos . Por ejemplo, las transacciones más largas pueden revertirse repetidamente en respuesta a múltiples transacciones más pequeñas, lo que desperdicia tiempo y energía. [2]

Hardware vs. software

Memoria transaccional de hardware que utiliza bits de lectura y escritura

La abstracción de la atomicidad en la memoria transaccional requiere un mecanismo de hardware para detectar conflictos y deshacer cualquier cambio realizado en los datos compartidos. [3] Los sistemas de memoria transaccional de hardware pueden comprender modificaciones en los procesadores, la memoria caché y el protocolo de bus para soportar transacciones. [4] [5] [6] [7] [8] Los valores especulativos en una transacción deben almacenarse en búfer y permanecer ocultos por otros subprocesos hasta el momento de confirmación. Se utilizan búferes grandes para almacenar valores especulativos mientras se evita la propagación de escritura a través del protocolo de coherencia de caché subyacente . Tradicionalmente, los búferes se han implementado utilizando diferentes estructuras dentro de la jerarquía de memoria, como colas de almacenamiento o cachés. Los búferes más alejados del procesador, como el caché L2, pueden contener más valores especulativos (hasta unos pocos megabytes). El tamaño óptimo de un búfer aún está en debate debido al uso limitado de transacciones en programas comerciales. [3] En una implementación de caché, las líneas de caché generalmente se amplían con bits de lectura y escritura. Cuando el controlador de hardware recibe una solicitud, el controlador usa estos bits para detectar un conflicto. Si se detecta un conflicto de serialización en una transacción paralela, se descartan los valores especulativos. Cuando se utilizan cachés, el sistema puede introducir el riesgo de conflictos falsos debido al uso de la granularidad de la línea de caché. [3] La memoria condicional de carga, enlace y almacenamiento (LL/SC) que ofrecen muchos procesadores RISC puede considerarse como el soporte de memoria transaccional más básico; sin embargo, LL/SC generalmente opera con datos que tienen el tamaño de una palabra de máquina nativa, por lo que solo se admiten transacciones de una sola palabra. [4] Aunque la memoria transaccional de hardware proporciona un rendimiento máximo en comparación con las alternativas de software, se ha visto un uso limitado en este momento.

La memoria transaccional de software proporciona semántica de memoria transaccional en una biblioteca de ejecución de software o en el lenguaje de programación [9] y requiere un soporte de hardware mínimo (normalmente una operación de intercambio y comparación atómica , o equivalente). Como desventaja, las implementaciones de software suelen tener una penalización de rendimiento, en comparación con las soluciones de hardware. La aceleración de hardware puede reducir algunos de los costos generales asociados con la memoria transaccional de software.

Debido a la naturaleza más limitada de la memoria transaccional de hardware (en las implementaciones actuales), el software que la utiliza puede requerir un ajuste bastante extenso para aprovecharla al máximo. Por ejemplo, el asignador de memoria dinámica puede tener una influencia significativa en el rendimiento y, de la misma manera, el relleno de la estructura puede afectar el rendimiento (debido a problemas de alineación de caché y compartición falsa); en el contexto de una máquina virtual, varios subprocesos en segundo plano pueden causar abortos inesperados de transacciones. [10]

Historia

Una de las primeras implementaciones de la memoria transaccional fue el buffer de almacenamiento controlado utilizado en los procesadores Crusoe y Efficeon de Transmeta . Sin embargo, esto solo se utilizó para facilitar optimizaciones especulativas para la traducción binaria, en lugar de cualquier forma de multiprocesamiento especulativo o exponerlo directamente a los programadores. Azul Systems también implementó memoria transaccional de hardware para acelerar sus dispositivos Java , pero esto también se ocultó a los extraños. [11]

Sun Microsystems implementó la memoria transaccional de hardware y una forma limitada de subprocesamiento múltiple especulativo en su procesador Rock de alta gama . Esta implementación demostró que podía usarse para la elisión de bloqueos y sistemas de memoria transaccional híbridos más complejos, donde las transacciones se manejan con una combinación de hardware y software. El procesador Rock fue cancelado en 2009, justo antes de la adquisición por parte de Oracle ; si bien los productos reales nunca se lanzaron, varios sistemas prototipo estaban disponibles para los investigadores. [11]

En 2009, AMD propuso la Advanced Synchronization Facility (ASF), un conjunto de extensiones x86 que proporcionan una forma muy limitada de compatibilidad con la memoria transaccional de hardware. El objetivo era proporcionar primitivas de hardware que pudieran utilizarse para una sincronización de nivel superior, como la memoria transaccional de software o algoritmos sin bloqueos. Sin embargo, AMD no ha anunciado si se utilizará ASF en productos y, de ser así, en qué plazo. [11]

Más recientemente, IBM anunció en 2011 que Blue Gene/Q tenía soporte de hardware tanto para memoria transaccional como para multihilo especulativo. La memoria transaccional se podía configurar en dos modos; el primero es un modo desordenado y de una sola versión, donde una escritura de una transacción causa un conflicto con cualquier transacción que lea la misma dirección de memoria. El segundo modo es para multihilo especulativo, proporcionando una memoria transaccional ordenada y con múltiples versiones. Los hilos especulativos pueden tener diferentes versiones de la misma dirección de memoria, y la implementación de hardware realiza un seguimiento de la edad de cada hilo. Los hilos más jóvenes pueden acceder a datos de hilos más antiguos (pero no al revés), y las escrituras en la misma dirección se basan en el orden de los hilos. En algunos casos, las dependencias entre hilos pueden hacer que las versiones más jóvenes se interrumpan. [11]

Las extensiones de sincronización transaccional (TSX) de Intel están disponibles en algunos procesadores Skylake . Anteriormente también se habían implementado en procesadores Haswell y Broadwell , pero ambas implementaciones resultaron defectuosas y se deshabilitó el soporte para TSX. La especificación TSX describe la API de memoria transaccional para que la utilicen los desarrolladores de software, pero no proporciona detalles sobre la implementación técnica. [11] La arquitectura ARM tiene una extensión similar. [12]

A partir de GCC 4.7, está disponible una biblioteca experimental para memoria transaccional que utiliza una implementación híbrida. La variante PyPy de Python también incorpora memoria transaccional al lenguaje.

Implementaciones disponibles

Véase también

Referencias

  1. ^ Harris, Tim; Larus, James; Rajwar, Ravi (2010-06-02). "Transactional Memory, 2nd edition". Síntesis Lectures on Computer Architecture . 5 (1): 1–263. doi :10.2200/S00272ED1V01Y201006CAC011. ISSN  1935-3235.
  2. ^ abcd "Memoria transaccional: historia y desarrollo". Kukuruku Hub . Consultado el 16 de noviembre de 2016 .
  3. ^ abc Solihin, Yan (2016). Fundamentos de la arquitectura multinúcleo paralela . Berkeley, California: Chapman & Hall. págs. 287–292. ISBN 978-1-4822-1118-4.
  4. ^ ab Herlihy, Maurice; Moss, J. Eliot B. (1993). "Memoria transaccional: soporte arquitectónico para estructuras de datos sin bloqueos" (PDF) . Actas del 20.º Simposio Internacional sobre Arquitectura de Computadores (ISCA) . pp. 289–300.
  5. ^ Stone, JM; Stone, HS; Heidelberger, P.; Turek, J. (1993). "Reservas múltiples y la actualización de Oklahoma". IEEE Parallel & Distributed Technology: Systems & Applications . 1 (4): 58–71. doi :10.1109/88.260295. S2CID  11017196.
  6. ^ Hammond, L; Wong, V.; Chen, M.; Carlstrom, BD; Davis, JD; Hertzberg, B.; Prabhu, MK; Honggo Wijaya; Kozyrakis, C.; Olukotun, K. (2004). "Coherencia y consistencia de la memoria transaccional". Actas del 31.º Simposio Internacional Anual sobre Arquitectura de Computadores (ISCA) . págs. 102–13. doi :10.1109/ISCA.2004.1310767.
  7. ^ Ananian, CS; Asanovic, K.; Kuszmaul, BC; Leiserson, CE; Lie, S. (2005). "Memoria transaccional ilimitada". 11.º Simposio internacional sobre arquitectura informática de alto rendimiento . págs. 316–327. doi :10.1109/HPCA.2005.41. ISBN 0-7695-2275-0.
  8. ^ "LogTM: memoria transaccional basada en registros" (PDF) . WISC.
  9. ^ "El lenguaje de programación transaccional ATOMOΣ" (PDF) . Stanford. Archivado desde el original (PDF) el 2008-05-21 . Consultado el 2009-06-15 .
  10. ^ Odaira, R.; Castanos, JG; Nakaike, T. (2013). "¿Los programas C y Java escalan de manera diferente en la memoria transaccional de hardware?". Simposio internacional IEEE de 2013 sobre caracterización de cargas de trabajo (IISWC) . p. 34. doi :10.1109/IISWC.2013.6704668. ISBN . 978-1-4799-0555-3.
  11. ^ abcde David Kanter (21 de agosto de 2012). "Análisis de la memoria transaccional de Haswell". Real World Technologies . Consultado el 19 de noviembre de 2013 .
  12. ^ "Arm lanza SVE2 y TME para la arquitectura de perfil A - Blog de procesadores - Procesadores - Comunidad Arm". community.arm.com . 18 de abril de 2019 . Consultado el 25 de mayo de 2019 .
  13. ^ "Intrínsecos de la extensión de memoria transaccional (TME)" . Consultado el 5 de mayo de 2020 .
  14. ^ "IBM instala memoria transaccional en la CPU". EE Times.
  15. ^ Brian Hall; Ryan Arnold; Peter Bergner; Wainer dos Santos Moschetta; Robert Enenkel; Pat Haugen; Michael R. Meissner; Alex Méricas; Philipp Oehler; Berni Schiefer; Brian F. Veale; Guerrero Suresh; Daniel Zabawa; Adhemerval Zanella (2014). Técnicas de optimización y ajuste del rendimiento para procesadores IBM, incluido IBM POWER8 (PDF) . Libros rojos de IBM. págs. 37–40. ISBN 978-0-7384-3972-3.
  16. ^ Wei Li, Funciones integradas de memoria transaccional de hardware del compilador IBM XL para IBM AIX en sistemas basados ​​en procesadores IBM POWER8
  17. ^ "Power ISA versión 3.1". openpowerfoundation.org. 2020-05-01 . Consultado el 2020-10-10 .
  18. ^ Java con 1000 núcleos: relatos de diseño conjunto de hardware y software en YouTube
  19. ^ "Control.Monad.STM". hackage.haskell.org . Consultado el 6 de febrero de 2020 .
  20. ^ "Página de inicio de STMX".
  21. ^ Wong, Michael. "Transactional Language Constructs for C++" (PDF) . Consultado el 12 de enero de 2011 .
  22. ^ "Breve tutorial sobre memoria transaccional GCC".
  23. ^ "Opciones del dialecto C - Uso de la colección de compiladores GNU (GCC)".
  24. ^ "TransactionalMemory - Wiki del CCG".
  25. ^ Rigo, Armin. "Usando todos estos núcleos: memoria transaccional en PyPy". europython.eu . Consultado el 7 de abril de 2015 .
  26. ^ "picotm - Gestor de transacciones portátil, integrado, personalizable y abierto".
  27. ^ "Concurrente::TVar".
  28. ^ Pizlo, Phil (15 de marzo de 2024). "Llevar la semántica de la memoria transaccional de Verse a C++" . Consultado el 18 de agosto de 2024 .

Lectura adicional

Enlaces externos