4 puntos por GN⁺ 2024-03-31 | 1 comentarios | Compartir por WhatsApp

Introducción a RCU

  • El sistema operativo es uno de los programas más sensibles al rendimiento en el uso diario.
  • El sistema operativo siempre puede ser más rápido, y los desarrolladores de kernels y controladores se dedican a optimizar el código.
  • El sistema operativo requiere concurrencia a gran escala, programa procesos e hilos en espacio de usuario, y tiene sus propios hilos y manejadores de interrupciones que interactúan con el hardware.

Cómo funciona RCU

  • Cuando se necesita cambiar de forma atómica datos que se leen con frecuencia pero se escriben rara vez (por ejemplo, los dispositivos USB conectados actualmente), se usa la estrategia RCU (Read, Copy, Update).
  • Se leen los datos, se copian para modificarlos y luego se actualiza atómicamente el puntero a la nueva versión.
  • Este método es fácil de usar y no tiene latencia de espera, pero puede provocar fugas de memoria.

Resolver el problema de las fugas de memoria

  • Para evitar fugas de memoria, en lugar de eliminar los datos antiguos dentro de la función de actualización, se puede posponer su eliminación hasta que ya no haya lectores usándolos.
  • Mientras los lectores están leyendo los datos, el escritor espera antes de eliminar los datos, lo que permite administrar la memoria de forma segura.

Uso real de RCU

  • RCU se usa decenas de miles de veces en Linux, y también se usa en la biblioteca C++ Folly de Facebook y en crossbeam-epoch de Rust.
  • RCU está impulsado por requisitos de rendimiento y latencia, y ofrece una forma de administración de memoria similar a la recolección de basura.

Ideas equivocadas sobre la recolección de basura

  • La creencia de que la recolección de basura es más lenta que la administración manual de memoria se derrumba rápidamente cuando se examinan los detalles.
  • La función free() no es gratis, y los asignadores de memoria deben mantener internamente mucho estado.
  • Los recolectores de basura modernos ofrecen optimizaciones de movimiento y generacionales para lograr alto rendimiento y buen desempeño de caché.

La ilusión del control

  • A veces los desarrolladores quieren construir sistemas en tiempo real, pero en la práctica no tienen un control perfecto sobre la administración de memoria.
  • El sistema operativo solo infiere la intención del desarrollador respecto a la asignación de memoria, y a veces un simple acceso a un puntero puede convertirse en E/S de disco.

Conclusión

  • No todo el software se beneficia de la recolección de basura, pero sigue siendo una herramienta útil y ya no debería verse con miedo, ni siquiera entre los programadores de sistemas.

Opinión de GN⁺

  • RCU es una técnica eficaz para aumentar la concurrencia manteniendo la consistencia de los datos en entornos multihilo. Esto es un factor muy importante en la computación de alto rendimiento o en sistemas en tiempo real.
  • El ejemplo de RCU, que rompe con las ideas preconcebidas sobre la recolección de basura, ofrece a los desarrolladores una nueva perspectiva sobre la administración de memoria. Esto es aún más cierto en el campo de la programación de sistemas, donde la gestión de memoria es especialmente importante.
  • Otros proyectos que ofrecen funciones similares a RCU incluyen ConcurrentLinkedQueue de Java y ConcurrentBag de .NET, que también proporcionan estructuras de datos lock-free.
  • Al adoptar la tecnología RCU, se deben considerar los requisitos del sistema y los objetivos de rendimiento, y entender tanto los beneficios obtenidos como los costos potenciales de usar esta técnica.
  • Este artículo puede ayudar a los desarrolladores a comprender más a fondo la administración de memoria y la concurrencia, replantear sus suposiciones existentes y explorar nuevas soluciones.

1 comentarios

 
GN⁺ 2024-03-31
Opiniones en Hacker News
  • Sugerencia de revisar las innovadoras técnicas de recolección de basura (GC) paralela de MPL y MaPLe

    • Ganaron el premio a mejor artículo en POPL 2024 y el premio ACM SIGPLAN al artículo de 2023
    • Las propuestas principales son las siguientes:
      • disentanglement basado en recolección de basura paralela demostrablemente eficiente
      • control automático de granularidad demostrablemente eficiente
  • Es interesante usar RCU como sincronización para la recolección de basura

    • Tiene sentido transferir la responsabilidad de liberar memoria del escritor al último lector
    • Para mejorar el rendimiento, quizá convenga trasladar la liberación de memoria a un proceso por lotes dedicado en lugar de dejarla en manos del lector
  • Malentendidos comunes sobre la gestión de memoria

    • Creer que los programadores conocen el tiempo de pausa óptimo para la gestión de memoria
    • En juegos y programas de trading de criptomonedas, los programadores realmente podrían conocer el tiempo de pausa óptimo
  • El caso de uso de RCU es convincente, pero la experiencia con la recolección de basura en otras situaciones no ha sido buena

    • Se lee como una afirmación de que las soluciones personalizadas de gestión de memoria pueden ofrecer el mejor rendimiento
    • Discusión sobre la confusión de que llamar a free() devuelve la memoria al SO
  • Al usar recolección de basura, las nuevas asignaciones se hacen en RAM y no en caché

    • Esto puede afectar mucho el rendimiento
    • Se ofrece un ejemplo de benchmark en el lenguaje Julia
  • Una buena recolección de basura por rastreo superó hace mucho a la gestión manual de memoria en términos de throughput

    • Últimamente, la latencia es aceptable para la mayoría de las aplicaciones
    • El uso de memoria es la principal consideración
  • Una de las cosas que combinan bien con la recolección de basura es async/await

    • En Rust, usar async/await junto con la gestión de memoria causa problemas
  • Resulta un poco sorprendente pasar, después de motivar RCU, a una discusión sobre la recolección de basura general

  • Al desarrollar software se consideran dos casos

    • Para las rutas calientes se usan asignadores personalizados, y en lo demás la recolección de basura es conveniente
  • El cambio de RCU a la recolección de basura por rastreo general parece una estrategia astuta

    • La gestión manual de memoria implica mucho más que simplemente llamar a malloc/free
  • Para los programadores de sistemas, es difícil identificar cuándo algo puede ser recolectado por el GC

  • Las herramientas de gestión de ciclos de vida de Rust y C++ ayudan a automatizar la liberación de memoria, pero no simplifican la complejidad