Bend - un lenguaje de alto nivel que corre en la GPU (usa HVM2)
(github.com/HigherOrderCO)- Bend es un lenguaje de programación de alto nivel que soporta procesamiento masivamente paralelo
- A diferencia de alternativas de bajo nivel como CUDA y Metal, Bend ofrece la sensación y las capacidades de lenguajes expresivos como Python y Haskell
- Incluye asignación rápida de objetos, funciones de orden superior con soporte completo para cierres, recursión sin restricciones e incluso continuaciones
- Sin embargo, corre sobre hardware masivamente paralelo como las GPU y muestra mejoras de velocidad casi lineales según la cantidad de núcleos
- No se requieren anotaciones explícitas de paralelismo: no hacen falta creación de hilos, bloqueos, mutex ni operaciones atómicas
- Bend está impulsado por el runtime HVM2
Demo rápida
Usar Bend
Actualmente no funciona en Windows; como alternativa hay que usar WSL2.
- Primero, hay que instalar Rust nightly.
- Luego, hay que instalar HVM2 y Bend:
cargo +nightly install hvm cargo +nightly install bend-lang - Por último, puedes escribir un archivo de Bend y ejecutarlo con uno de estos comandos:
bend run # usa el intérprete de Rust (secuencial) bend run-c # usa el intérprete de C (paralelo) bend run-cu # usa el intérprete de CUDA (masivamente paralelo) - También puedes compilar Bend a archivos C/CUDA independientes usando
gen-cygen-cupara obtener el máximo rendimiento. Sin embargo, la generación de código aún está en una etapa temprana y no es tan madura como compiladores de punta como GCC o GHC.
Programación paralela en Bend
- Para escribir programas paralelos en Bend... no tienes que hacer nada. Solo debes escribirlos de forma que no sean inherentemente secuenciales.
- Por ejemplo, la siguiente expresión no puede ejecutarse en paralelo:
porque(((1 + 2) + 3) + 4)+4depende de+3, y+3depende de(1+2). - Pero la siguiente expresión sí puede ejecutarse en paralelo:
porque((1 + 2) + (3 + 4))(1+2)y(3+4)son independientes. Según el principio básico de Bend, todo lo que pueda ejecutarse en paralelo se ejecutará en paralelo.
Código de ejemplo
-
Como ejemplo más completo, considera el siguiente código:
# red de ordenamiento = rotación de árbol def sort(d, s, tree): switch d: case 0: return tree case _: (x, y) = tree lft = sort(d-1, 0, x) rgt = sort(d-1, 1, y) return rots(d, s, lft, rgt) # rotación de subárbol def rots(d, s, tree): switch d: case 0: return tree case _: (x, y) = tree return down(d, s, warp(d-1, s, x, y)) -
Este archivo implementa un clasificador bitónico usando rotaciones inmutables de árbol. No es un algoritmo del que se esperaría que corriera rápido en una GPU. Sin embargo, como usa un enfoque de divide y vencerás, es inherentemente paralelo. Bend lo ejecuta en múltiples hilos. Algunos benchmarks:
- CPU, Apple M3 Max, 1 hilo: 12.15 segundos
- CPU, Apple M3 Max, 16 hilos: 0.96 segundos
- GPU, NVIDIA RTX 4090, 16k hilos: 0.21 segundos
- Se logra una aceleración de 57x sin hacer nada. No hay manejo explícito de creación de hilos, bloqueos ni mutex. Simplemente se le pidió a Bend que ejecutara el programa en una RTX.
Soporte para varios sistemas paralelos
-
Bend no está limitado a paradigmas específicos como tensores o matrices. En Bend se puede emular cualquier sistema paralelo, desde shaders hasta el modelo de actores estilo Erlang.
-
Por ejemplo, para renderizar imágenes en tiempo real, se puede asignar un árbol inmutable para cada frame:
# dado un shader, devuelve una imagen rectangular def render(depth, shader): bend d = 0, i = 0: when d < depth: color = (fork(d+1, i*2+0), fork(d+1, i*2+1)) else: width = depth / 2 color = shader(i % width, i / width) return color # dada una posición, devuelve un color # en esta demo, simplemente ejecuta un bucle ocupado def demo_shader(x, y): bend i = 0: when i < 5000: color = fork(i + 1) else: color = 0x000001 return color # renderiza una imagen de 256x256 usando demo_shader def main: return render(16, demo_shader) -
Realmente funciona. Incluso algoritmos complejos se paralelizan bien en Bend. La comunicación de larga distancia se realiza mediante reducción beta global (de acuerdo con el cálculo de interacciones) y se sincroniza de forma correcta y eficiente gracias al linker atómico de HVM2.
Material adicional
- Para empezar de inmediato, revisa el GUIDE.md de Bend.
- Para ver la lista de funciones, revisa FEATURES.md.
- Para entender la tecnología de Bend, revisa el paper de HVM2.
- Bend es desarrollado por HigherOrderCO.com; únete a Discord.
Opinión de GN⁺
- Simplificación de la programación paralela: Bend simplifica enormemente la programación paralela, de modo que incluso ingenieros de software principiantes pueden acceder fácilmente a ella. Esto reduce de forma significativa la barrera de entrada a la programación paralela.
- Soporte para diverso hardware: Bend puede ejecutarse eficientemente no solo en CPU sino también en GPU, por lo que puede aprovecharse en distintos entornos de hardware.
- Lenguaje expresivo: Al combinar las ventajas de Python y Haskell, permite escribir código expresivo. Esto mejora la legibilidad y el mantenimiento del código.
- Generación de código en etapa temprana: Actualmente, la generación de código de Bend está en una etapa temprana, por lo que su rendimiento puede quedar por debajo del de compiladores maduros. Esto requiere mejoras a futuro.
- Soporte para varios sistemas paralelos: Bend no está limitado a un paradigma específico y soporta diversos sistemas paralelos, lo que permite una programación flexible. Esto hace posible usar Bend en múltiples áreas de aplicación.
1 comentarios
Comentarios de Hacker News
Resumen de comentarios de Hacker News
Comparación de rendimiento entre Python y PyPy
Comentarios positivos
Opiniones críticas
Expectativas sobre la programación paralela
Comparación de rendimiento
Expectativas sobre la evolución del proyecto
Visión escéptica
Perspectiva positiva
Características del lenguaje de Bend