GN⁺: Bend - GPU에서 실행되는 고급 언어 (HVM2 사용)
(github.com/HigherOrderCO)- Bend는 대규모 병렬 처리를 지원하는 고수준 프로그래밍 언어
- CUDA와 Metal 같은 저수준 대안과 달리, Bend는 Python과 Haskell 같은 표현력 있는 언어의 느낌과 기능을 제공함
- 빠른 객체 할당, 완전한 클로저 지원을 갖춘 고차 함수, 제한 없는 재귀, 심지어 연속성까지 포함됨
- 그러나 GPU와 같은 대규모 병렬 하드웨어에서 실행되며, 코어 수에 따라 거의 선형적인 속도 향상을 보임
- 명시적인 병렬 주석이 전혀 필요 없음: 스레드 생성, 잠금, 뮤텍스, 원자적 연산이 필요하지 않음
- Bend는 HVM2 런타임에 의해 구동됨
빠른 데모
Bend 사용하기
현재 Windows에서는 작동하지 않음, WSL2를 대안으로 사용해야 함.
- 먼저, Rust nightly를 설치해야 함.
- 그런 다음, HVM2와 Bend를 설치해야 함:
cargo +nightly install hvm cargo +nightly install bend-lang
- 마지막으로 Bend 파일을 작성하고 다음 명령어 중 하나로 실행할 수 있음:
bend run # Rust 인터프리터 사용 (순차적) bend run-c # C 인터프리터 사용 (병렬) bend run-cu # CUDA 인터프리터 사용 (대규모 병렬)
- 또한 최대 성능을 위해
gen-c
와gen-cu
를 사용하여 Bend를 독립 실행형 C/CUDA 파일로 컴파일할 수 있음. 그러나 코드 생성은 아직 초기 단계에 있으며, GCC나 GHC 같은 최첨단 컴파일러만큼 성숙하지 않음.
Bend에서 병렬 프로그래밍
- Bend에서 병렬 프로그램을 작성하려면... 아무것도 하지 않아도 됨. 단, 본질적으로 순차적이지 않게 작성해야 함.
- 예를 들어, 다음 표현식은 병렬로 실행될 수 없음:
(((1 + 2) + 3) + 4)
+4
는+3
에 의존하고,+3
은(1+2)
에 의존하기 때문임. - 그러나 다음 표현식은 병렬로 실행될 수 있음:
((1 + 2) + (3 + 4))
(1+2)
와(3+4)
는 독립적이기 때문임. Bend의 기본 원칙에 따라 병렬로 실행될 수 있는 모든 것은 병렬로 실행됨.
예제 코드
-
보다 완전한 예제로, 다음 코드를 고려해보자:
# 정렬 네트워크 = 트리 회전 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) # 서브 트리 회전 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))
-
이 파일은 불변 트리 회전을 사용한 비토닉 정렬기를 구현함. 이는 GPU에서 빠르게 실행될 것으로 예상되지 않는 알고리즘임. 그러나 분할 정복 접근 방식을 사용하므로 본질적으로 병렬적임. Bend는 이를 다중 스레드로 실행함. 몇 가지 벤치마크:
- CPU, Apple M3 Max, 1 스레드: 12.15초
- CPU, Apple M3 Max, 16 스레드: 0.96초
- GPU, NVIDIA RTX 4090, 16k 스레드: 0.21초
- 57배 속도 향상을 아무것도 하지 않고 달성함. 스레드 생성, 잠금, 뮤텍스의 명시적 관리가 없음. 단지 Bend에게 RTX에서 프로그램을 실행하도록 요청했을 뿐임.
다양한 병렬 시스템 지원
-
Bend는 텐서나 행렬 같은 특정 패러다임에 국한되지 않음. 셰이더에서 Erlang과 같은 액터 모델까지 모든 병렬 시스템을 Bend에서 에뮬레이트할 수 있음.
-
예를 들어, 실시간으로 이미지를 렌더링하려면 각 프레임에 불변 트리를 할당할 수 있음:
# 셰이더를 주어지면, 사각형 이미지를 반환 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 # 위치를 주어지면, 색상을 반환 # 이 데모에서는 단순히 바쁜 루프를 돌림 def demo_shader(x, y): bend i = 0: when i < 5000: color = fork(i + 1) else: color = 0x000001 return color # demo_shader를 사용하여 256x256 이미지를 렌더링 def main: return render(16, demo_shader)
-
실제로 작동함. 복잡한 알고리즘도 Bend에서 잘 병렬화됨. 장거리 통신은 글로벌 베타 감소(상호작용 계산법에 따라)로 수행되며, HVM2의 원자적 링커에 의해 정확하고 효율적으로 동기화됨.
추가 자료
- 바로 시작하려면, Bend의 GUIDE.md를 확인할 것.
- 기능 목록을 보려면, FEATURES.md를 확인할 것.
- Bend의 기술을 이해하려면, HVM2의 논문을 확인할 것.
- Bend는 HigherOrderCO.com에서 개발됨 - Discord에 참여할 것.
GN⁺의 의견
- 병렬 프로그래밍의 단순화: Bend는 병렬 프로그래밍을 매우 단순화하여, 초급 소프트웨어 엔지니어도 쉽게 접근할 수 있음. 이는 병렬 프로그래밍의 진입 장벽을 크게 낮춤.
- 다양한 하드웨어 지원: Bend는 CPU뿐만 아니라 GPU에서도 효율적으로 실행될 수 있어, 다양한 하드웨어 환경에서 활용 가능함.
- 표현력 있는 언어: Python과 Haskell의 장점을 결합하여, 표현력 있는 코드를 작성할 수 있음. 이는 코드의 가독성과 유지보수성을 높임.
- 초기 단계의 코드 생성: 현재 Bend의 코드 생성은 초기 단계에 있어, 성숙한 컴파일러와 비교했을 때 성능이 떨어질 수 있음. 이는 향후 개선이 필요함.
- 다양한 병렬 시스템 지원: Bend는 특정 패러다임에 국한되지 않고, 다양한 병렬 시스템을 지원하여 유연한 프로그래밍이 가능함. 이는 다양한 응용 분야에서 Bend를 활용할 수 있게 함.
Hacker News 의견
해커뉴스 댓글 모음 요약
-
Python과 PyPy 성능 비교
- Python과 PyPy로 동일한 코드를 실행했을 때, PyPy가 훨씬 빠름.
- Apple M3 Max와 NVIDIA RTX 4090에서의 벤치마크 결과 공유.
- Intel i7-1270P에서의 성능이 매우 느림.
- Mac 외의 다른 플랫폼에서도 테스트가 필요함.
-
긍정적인 피드백
- 프로젝트의 초기 단계임을 감안할 때, 성과를 칭찬함.
- Futhark과 비교하여, 다양한 타겟을 지원하지 않는 점이 아쉬움.
- 성능 문제는 해결 가능할 것으로 보임.
-
비판적인 의견
- 초기 버전임에도 불구하고 많은 비판을 받고 있음.
- 홈페이지가 직관적이고 이해하기 쉬움.
- 병렬 알고리즘에 대한 기대와 현실의 차이를 언급함.
-
병렬 프로그래밍에 대한 기대
- 병렬 프로그래밍의 미래에 대한 기대를 표현함.
- Rust와 Shadertoy를 통해 병렬 프로그래밍을 실험한 경험 공유.
- GPU를 활용한 일반 병렬 언어에 대한 기대감.
-
성능 비교
- C++로 작성한 간단한 루프가 Bend와 유사한 성능을 보임.
- 최적화된 C++ 코드가 훨씬 빠름.
-
프로젝트의 발전 기대
- 자동 병렬화의 어려움을 극복한 점을 칭찬함.
- 프로젝트의 발전을 기대함.
-
회의적인 시각
- Bend의 제한된 DSL 특성을 지적함.
- 성능이 좋지 않다는 점을 강조함.
- 실제 고성능 병렬 컴퓨팅에서는 배열이 중요함을 언급함.
- Bend의 유용성에 대해 회의적임.
-
긍정적인 전망
- Bend가 GPU 활용을 극대화할 수 있는 가능성을 언급함.
- LLMs 외에도 GPU를 활용할 수 있는 다양한 가능성을 기대함.
-
Bend의 언어적 특성
- Bend의 간단한 사용법과 성능 향상을 칭찬함.
- 24비트 정수만 지원하는 점이 아쉬움.
- 더 높은 비트 정수 지원이 필요함을 언급함.